1

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?

Eric Yu
  • 11
  • 1
  • 4

2 Answers2

0

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.

user207421
  • 305,947
  • 44
  • 307
  • 483
-2

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 (i.e. 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 (i.e. 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.

jayunit100
  • 17,388
  • 22
  • 92
  • 167
  • Thanks for your quick replay. This is a socket channel connect to a Netty server. I send one request to server, the server returned just 48 bytes, the code is executed only when selector.select() return, and selectionKey is readable. So I totally confused. – Eric Yu Dec 15 '11 at 04:14
  • BTW, as I mentioned in title, what I read from the socketChannel is the 48 bytes return from server, the problem is I can always read the same data from the socketChannel. And since the data is correct, so I can decode it, so this never stop :-( – Eric Yu Dec 15 '11 at 04:19
  • Thus --- it is not a bug in your code. Can you clarify what data your reading from Netty ? – jayunit100 Dec 15 '11 at 13:45
  • None of this is correct. A `read()` will return zero if there is no room in the buffer, or in non-blocking mode if there is no data ready to read. It will return -1 at end of stream, i.e. when all data has been read and the peer has closed the connection. – user207421 Dec 15 '11 at 21:43
  • @EJP Yes.... thats actually true -- a read() can return 0 in the case that the buffer has no room...... but in this case... im assuming thats not an issue. Probably a better way to phrase the point... I will edit the response accordingly. – jayunit100 Dec 16 '11 at 03:06