0

我已经有一段时间遇到这个问题了。系统的快速解释:

一个简单的应用程序将通过 tcp 连接读取数据。应用程序使用 Socketchannel 对象建立数据通信线路。与硬件的连接已建立,应用程序在抛出错误之前处理了大约 400 - 700 个数据包:

在 sun.nio.ch.SocketDispatcher.read0(Native Method) 在 sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43) 在 sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:218) 在 sun .nio.ch.IOUtil.read(IOUtil.java:186) 在 sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:359)

我怀疑它与操作系统(Windows 7)缓冲区有关,尽管我尝试了一些解决方法(增加 JVM 堆大小,并为 TCP 设置创建额外的注册表变量),但没有运气。

使用wireshark检查包数据,出现错误时可以看到如下信息

[TCP Window Full] 5001 > 49995 [PSH, ACK] Seq=123177 Ack=1 Win=200 Len=176
[TCP ZeroWindow] 49995 > 5001 [ACK] Seq=1 Ack=123353 Win=0 Len=0

然后是一系列

[TCP 重复 ACK 144#1] 5001 > 49995 [ACK] Seq=123353 Ack=1 Win=200 Len=0

直到连接终止。

我希望过去可能有人遇到过类似的问题,或者可以就我可能忽略的事情提供一些指导。

这是读取数据并引发错误的示例代码。

    try{
            do{
                socketChannel.read(syncBuf); 
                start = syncBuf.get(0);
                int b = start;
                System.out.println("start byte is " + b);
                syncBuf.clear(); 
            }while(start != INIT_BYTE);
        }catch(Exception e){      
            e.printStackTrace();
        }

        packetBuf.order(ByteOrder.LITTLE_ENDIAN);
        packetBuf.clear();

        try{
            while(socketChannel.read(packetBuf) != 206){
                nrBytesRead += socketChannel.read(packetBuf);
            }
        }catch(Exception e){
            ApplicationLogger.log("Error at INIT_BYTE loop ", "ERROR");
        }

非常感谢。

4

1 回答 1

0

我觉得你这里有问题:

while(socketChannel.read(packetBuf) != 206)
{
    nrBytesRead += socketChannel.read(packetBuf);
}

socketChannel.read(packetBuf)将返回这次读取的数字,而不是总数,我猜这就是 206,总读取。

你可能想这样做:

do
{
    nrBytesRead += socketChannel.read(packetBuf);
}
while (nrBytesRead != 206)
于 2013-05-29T10:12:26.040 回答