简体   繁体   English

java nio socketChannel读取总是返回相同的数据

[英]java nio socketChannel read always return same data

In client side, read code: 在客户端,阅读代码:

byte[] bytes = new byte[50]; //TODO should reuse buffer, for test only
ByteBuffer dst = ByteBuffer.wrap(bytes);
int ret = 0;
int readBytes = 0;
boolean fail = false;
try {
    while ((ret = socketChannel.read(dst)) > 0) {
    readBytes += ret;
    System.out.println("read " + ret + " bytes from socket " + dst);
    if (!dst.hasRemaining()) {
        break;
    }
    }
    int pos = dst.position();
    byte[] data = new byte[pos];
    dst.flip();
    dst.get(data);
    System.out.println("read data: " + StringUtil.toHexString(data));
} catch (Exception e) {
    fail = true;
    handler.onException(e);
}

The problem is socketChannel.read() always return positive, I checked the return buffer, the data is duplicate N times, it likes the low level socket buffer's position is not move forward. 问题是socketChannel.read()总是返回正数,我检查了返回缓冲区,数据重复了N次,就像低级套接字缓冲区的位置不向前一样。 Any idea? 任何想法?

If the server only returned 48 bytes, your code must have blocked in the read() method trying to get the 49th and 50th bytes. 如果服务器仅返回48个字节,则您的代码必须在read()方法中被阻塞,试图获取第49个和第50个字节。 So either your '50' is wrong or you will have to restructure your code to read and process whatever you get as you get it rather than trying to fill buffers first. 因此,要么您的“ 50”是错误的,要么您将不得不重组代码以读取和处理获得的内容,而不是先尝试填充缓冲区。 And this can't possibly be the code where you think you always got the same data. 而且这可能不是您认为始终获得相同数据的代码。 The explanation for that would be failure to compact the buffer after the get, if you reuse the same buffer for the next read, which you should do, but your posted code doesn't do. 如果您在下一次读取时重复使用相同的缓冲区,应该这样做,但是发布的代码却不执行,这样的解释将是在获取后无法压缩缓冲区。

1 : This might not be a bug ! 1:这可能不是错误!

[assuming that there is readable data in the buffer]... [假设缓冲区中有可读数据] ...

You would expect a -1 at the end of the stream... See http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/channels/SocketChannel.html#read%28java.nio.ByteBuffer%29 您可能希望流末尾为-1 ...请参阅http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/channels/SocketChannel.html#read%28java。 nio.ByteBuffer%29

If you are continually recieving a positive value from the read() call, then you will need to determine why data is being read continually. 如果您不断从read()调用中接收到正值,那么您将需要确定为什么要连续读取数据。

Of course, the mystery herein ultimately lies in the source data (ie the SocketChannel which you are read data from). 当然,这里的奥秘最终在于源数据(即从中读取数据的SocketChannel)。

2: Explanation of your possible problems 2:您可能遇到的问题的说明

If your socket channel is coming from a REAL file, which is finite then your file is really big, and eventually, the read() operation will return 0... eventually... 如果套接字通道来自有限的REAL文件,那么您的文件确实很大,并且最终,read()操作将返回0 ...最终...

If, on the other hand, your socket channel is listening to a source of data which you EXPECT to be finite (ie a serialized object stream, for example), I would double check the source --- maybe your finite stream is simply producing more and more data... and you are correctly consuming it. 另一方面,如果您的套接字通道正在侦听您期望是有限的数据源(例如,序列化的对象流),那么我将仔细检查该源-也许您的有限流只是在生成越来越多的数据...您正在正确地使用它。

3: Finally some advice 3:最后一些建议

A trick for debugging this type of error is playing with the ByteBuffer input to your read method : the nice thing about java.nio's ByteBuffers is that, since they are more object oriented then the older byte[] writers, you can get very fine-grained debugging of their operations. 调试此类错误的一个技巧是将ByteBuffer输入读取方法中使用:关于java.nio的ByteBuffer的好处是,由于它们比旧的byte []编写器更面向对象,因此您可以-细粒度的操作调试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM