gpt4 book ai didi

java - Java 网络程序中通过套接字发送的字符串中的最后几个字符有时会丢失

转载 作者:行者123 更新时间:2023-12-01 22:19:43 26 4
gpt4 key购买 nike

现在,我正在尝试编写一个基于 GUI 的 Java tic-tac-toe 游戏,该游戏通过网络连接运行。此时它基本上可以工作,但是我遇到一个间歇性错误,其中通过网络连接发送的几个字符在游戏过程中丢失。当 println 语句添加到消息发送/读取时,一种情况如下所示:

玩家 1:刚刚发送第 14 行第 11 列游戏结束 true

玩家2:刚刚收到第 14 行第 11 列 GAMEOV

我很确定当我通过网络阅读时会发生错误。读取发生在它自己的线程中,BufferedReader 包裹在套接字的 InputStream 周围,如下所示:

try {
int input;
while((input = dataIn.read()) != -1 ){
char msgChar = (char)input;
String message = msgChar + "";
while(dataIn.ready()){
msgChar = (char)dataIn.read();
message+= msgChar;
}
System.out.println("Just received " + message);
this.processMessage(message);

}
this.sock.close();


}

我的 sendMessage 方法非常简单(只是对包裹在套接字输出流的 DataOutputStream 进行写入),所以我认为问题不会发生在那里:

try {
dataOut.writeBytes(message);
System.out.println("Just sent " + message);
}

如有任何想法,我们将不胜感激。谢谢!

最佳答案

事实证明,ready() 方法仅保证下一次读取不会阻塞。因此,!ready() 不能保证下一次读取会阻塞。只是它可以。

我认为这里的问题与 TCP 堆栈本身有关。由于面向流,当字节写入套接字时,TCP 不保证其发送的字节的顺序或分组。我怀疑 TCP 堆栈正在以一种对其有意义的方式分解发送的字符串,并且在此过程中,ready() 方法必须检测到流中某种潜在的中断,并返回 false,尽管事实上,可以获得更多信息。

我重构了代码,为每条发送的消息添加换行符,然后简单地执行 readLine() 。这使得我的网络协议(protocol)能够依赖换行符作为消息分隔符,而不是 read() 方法。我很高兴地说这解决了问题。

感谢您的所有投入!

关于java - Java 网络程序中通过套接字发送的字符串中的最后几个字符有时会丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30141635/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com