套接字通道 - readIntoNativeBuffer()错误

时间:2013-05-29 09:54:59

标签: java tcp buffer buffer-overflow socketchannel

我一直在经历这个问题。系统的快速解释:

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

  

at sun.nio.ch.SocketDispatcher.read0(Native Method)       at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43)       在sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:218)       at 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 Dup 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");
        }

非常感谢。

1 个答案:

答案 0 :(得分:0)

我认为你有问题:

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

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

您可能想要这样做:

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