流中的套接字服务器流消息混合
Socket server stream messages in stream are mixed
我正在使用服务器套接字机制实现多人游戏。
- 游戏是运行单循环机制。
- 服务器只向每个连接的玩家广播任何消息。
- 服务器为每个连接的玩家创建线程
- 消息是 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");
}
上面的方法在主游戏循环中是运行。它检查 inputStream 中是否有内容,然后读取它。
这是正确消息的样子:
GOT MESSAGE: {"type":"UPDATE_STATE","content":null,"senderName":"GRACZ 52","posX":10.0,"posY":5.0}
当有 2 个玩家时它工作正常,但连接的玩家越多,就越有可能收到这样的消息(或类似的损坏消息):
GOT MESSAGE: 0} U{"type":"UPDATE_STATE","content":null,"senderName":"GRACZ 65","posX":10.0,"posY":5.0}
或
GOT MESSAGE: {"type":"UPDATE_STATE","content":null,"senderName":"GRACZ 24","pos
消息中有不同的错误,如Y字母、半条消息或一行中的多条消息。为什么会发生这样的事情?看起来当有更多的玩家并且他们在服务器端写入输出流时,这个流还没有被读取所以他们正在追加和追加。但是并没有解释为什么会出现问题,最重要的是,如何解决?
我可以将阅读流移动到另一个线程,因为 in.readUTF() 锁定了进程,但我想在主游戏循环中保持同步,我认为这不会有帮助(我错了吗?)
您需要在所有 PlayerThread 之间通用的对象上同步您的写入循环,以便消息不会交错。
synchronized(/*Should be a "global" server object*/) {
for (PlayerThread p : players) {
p.getOut().writeUTF(inputMessage);
}
}
我正在使用服务器套接字机制实现多人游戏。
- 游戏是运行单循环机制。
- 服务器只向每个连接的玩家广播任何消息。
- 服务器为每个连接的玩家创建线程
- 消息是 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");
}
上面的方法在主游戏循环中是运行。它检查 inputStream 中是否有内容,然后读取它。
这是正确消息的样子:
GOT MESSAGE: {"type":"UPDATE_STATE","content":null,"senderName":"GRACZ 52","posX":10.0,"posY":5.0}
当有 2 个玩家时它工作正常,但连接的玩家越多,就越有可能收到这样的消息(或类似的损坏消息):
GOT MESSAGE: 0} U{"type":"UPDATE_STATE","content":null,"senderName":"GRACZ 65","posX":10.0,"posY":5.0}
或
GOT MESSAGE: {"type":"UPDATE_STATE","content":null,"senderName":"GRACZ 24","pos
消息中有不同的错误,如Y字母、半条消息或一行中的多条消息。为什么会发生这样的事情?看起来当有更多的玩家并且他们在服务器端写入输出流时,这个流还没有被读取所以他们正在追加和追加。但是并没有解释为什么会出现问题,最重要的是,如何解决?
我可以将阅读流移动到另一个线程,因为 in.readUTF() 锁定了进程,但我想在主游戏循环中保持同步,我认为这不会有帮助(我错了吗?)
您需要在所有 PlayerThread 之间通用的对象上同步您的写入循环,以便消息不会交错。
synchronized(/*Should be a "global" server object*/) {
for (PlayerThread p : players) {
p.getOut().writeUTF(inputMessage);
}
}