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);
}
}