简体   繁体   中英

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. 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. 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. 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 !

[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

If you are continually recieving a positive value from the read() call, then you will need to determine why data is being read continually.

Of course, the mystery herein ultimately lies in the source data (ie the SocketChannel which you are read data from).

2: Explanation of your possible problems

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...

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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