Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 流中的套接字服务器流消息是混合的_Java_Json_Sockets_Stream_Message - Fatal编程技术网

Java 流中的套接字服务器流消息是混合的

Java 流中的套接字服务器流消息是混合的,java,json,sockets,stream,message,Java,Json,Sockets,Stream,Message,我正在用服务器套接字机制实现多人游戏 游戏运行在一个循环机制中 服务器只向连接的每个玩家广播任何消息 服务器为每个连接的播放器创建线程 消息是JSON,每100毫秒从客户端发送一次 消息由服务器广播,由客户端读取,没有任何间隔 这是服务器循环: while (true) { try { System.out.println("LISTENING..."); Socket c

我正在用服务器套接字机制实现多人游戏

  • 游戏运行在一个循环机制中
  • 服务器只向连接的每个玩家广播任何消息
  • 服务器为每个连接的播放器创建线程
  • 消息是JSON,每100毫秒从客户端发送一次
  • 消息由服务器广播,由客户端读取,没有任何间隔
这是服务器循环:

    while (true) {
                try {
                    System.out.println("LISTENING...");
                    Socket clientSocket = serverSocket.accept();
                    System.out.println("GOT CONNECTION");

                    PlayerThread playerThread = new PlayerThread(clientSocket);
                    playerThread.start();
                } catch (IOException e) {
                    LOGGER.log(Level.SEVERE, "Exception occured on server");
                    break;
                }
            }
这是PlayerThread循环:

        while (true) {
            try {
                String inputMessage = in.readUTF();
                System.out.println("GOT: " + inputMessage);
                JsonNode jsonNode = objectMapper.readTree(inputMessage);
                String senderName = jsonNode.get("senderName").asText();

                if (!players.contains(this)) {
                    playerName = senderName;
                    players.add(this);
                }

                for (PlayerThread p : players) {
                    p.getOut().writeUTF(inputMessage);
                }
最后听留言:

public void listen() {
        if (connected) {
            try {
                if (in.available() > 0) {
                    String inputMessage = in.readUTF();
                    System.out.println("GOT MESSAGE: " + inputMessage);
                    handleMessages(inputMessage);
                }
            } catch (IOException e) {
                LOGGER.log(Level.INFO, "Connection lost");
                connected = false;
            }
        } else
            LOGGER.log(Level.INFO, "Player is not connected");
    }
GOT MESSAGE: 0} U{"type":"UPDATE_STATE","content":null,"senderName":"GRACZ 65","posX":10.0,"posY":5.0}
上述方法在主游戏循环中运行。它检查inputStream中是否有内容,然后读取它

这是正确消息的样子:

GOT MESSAGE: {"type":"UPDATE_STATE","content":null,"senderName":"GRACZ 52","posX":10.0,"posY":5.0}
当有两个玩家时,它可以正常工作,但玩家连接越多,就越有可能收到这样的消息(或类似的坏消息):

消息中有不同的错误,如Y字母、半个消息或一行多个消息。为什么会发生这样的事情?看起来,当有更多的玩家在服务器端写入输出流时,这个流还没有被读取,所以他们在不断追加。但这并不能解释为什么会有破裂,最重要的是,如何解决它


我可以将读取流移动到另一个线程,因为in.readUTF()会锁定进程,但我想让它在主游戏循环中保持同步,我不认为这会有帮助(我错了吗?

您需要在所有PlayerThreads之间共用的对象上同步写入循环,以便消息不会交错

         synchronized(/*Should be a "global" server object*/) {
           for (PlayerThread p : players) {
                p.getOut().writeUTF(inputMessage);
            }
         }

我尝试过:synchronized(this){p.getOut().writeUTF(inputMessage);}我认为原因可能在于java套接字实现内部,或者可能是我使用了错误类型的流?synchronized(this)不起作用,因为这是PlayerThread的不同实例。你需要在一个全局/共享对象上同步你是对的,在那之后我把它改为在流本身上同步,它看起来更好。存在性能问题,但我不确定这是由多个java应用程序运行还是由同步引起的。
         synchronized(/*Should be a "global" server object*/) {
           for (PlayerThread p : players) {
                p.getOut().writeUTF(inputMessage);
            }
         }