通过套接字发送的字符串中的最后几个字符有时在Java网络程序中丢失 [英] Last few chars in a string sent over socket sometimes missing in Java network program

查看:64
本文介绍了通过套接字发送的字符串中的最后几个字符有时在Java网络程序中丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在,我正在尝试编写基于GUI的Java井字游戏,该游戏可通过网络连接运行.在这一点上它基本上可以正常工作,但是我有一个间歇性错误,即在游戏过程中丢失了通过网络连接发送的几个字符.将println语句添加到消息发送/读取中时,情况如下:

Right now, I'm trying to write a GUI based Java tic-tac-toe game that functions over a network connection. It essentially works at this point, however I have an intermittent error in which several chars sent over the network connection are lost during gameplay. One case looked like this, when println statements were added to message sends/reads:

播放器1:刚刚发送的第14列第11列GAMEOVER是正确的

Player 1: Just sent ROW 14 COLUMN 11 GAMEOVER true

播放器2:刚收到第14列第11行GAMEOV

Player 2: Just received ROW 14 COLUMN 11 GAMEOV

我很确定我通过网络阅读时发生了错误.读取是在其自己的线程中进行的,其中BufferedReader包裹在套接字的InputStream周围,如下所示:

Im pretty sure the error is happening when I read over the network. The read takes place in its own thread, with a BufferedReader wrapped around the socket's InputStream, and looks like this:

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进行写操作),所以我认为问题不在那里:

My sendMessage method is pretty simple, (just a write over a DataOutputStream wrapped around the socket's outputstream) so I don't think the problem is happening there:

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

任何想法都将不胜感激.谢谢!

Any thoughts would be highly appreciated. Thanks!

推荐答案

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

As it turns out, the ready() method guaruntees only that the next read WON'T block. Consequently, !ready() does not guaruntee that the next read WILL block. Just that it could.

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

I believe that the problem here had to do with the TCP stack itself. Being stream-oriented, when bytes were written to the socket, TCP makes no guarantees as to the order or grouping of the bytes it sends. I suspect that the TCP stack was breaking up the sent string in a way that made sense to it, and that in the process, the ready() method must detect some sort of underlying break in the stream, and return false, in spite of the fact that more information is available.

我重构了代码,在每个发送的消息中添加了换行符,然后只需执行一次readLine()即可.这允许我的网络协议依赖于换行符作为消息定界符,而不是ready()方法.我很高兴地说这可以解决问题.

I refactored the code to add a newline character to every message send, then simply performed a readLine() instead. This allowed my network protocol to be dependent on the newline character as a message delimiter, rather than the ready() method. I'm happy to say this fixed the problem.

感谢您的所有投入!

这篇关于通过套接字发送的字符串中的最后几个字符有时在Java网络程序中丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆