I have a client-server application communicating over Java NIO sockets which makes use of the SocketChannelImpl
class underneath. When from the senders side, I send a ByteBuffer array of length n
elements, the client always receives ByteBuffer array of length n+1
elements with the last ByteBuffer always being of the size 0
.
I was wondering if that is some sort of an EOF indicator automatically sent by the SocketChannelImpl
class to indicate a completed send of an array of ByteBuffers so that when the receiving side receives an array ByteBuffers followed by a BytBuffer of size 0
it knows that it has correctly received the ByteBuffer array that was sent from the senders side?
Update: Adding example to further elaborate on my question:
Whenever a call to SocketChannel.write(ByteBuffer[] srcs, int offset, int length) is made on the senders side and SocketChannel.read(ByteBuffer srcs) is made on the receivers side, I log the length of the array and the size of its element. Following is a set of logs from senders and receiver side:
Sender:
Writing using:write(ByteBuffer[] srcs, int offset, int length)
srcs.length == 2, totalBytesWritten = 1326
Receiver:
Read using read(ByteBuffer src)
totalBytesRead:4
totalBytesRead:1322
totalBytesRead:0
What I am asking is, why on the receiver side even though the amount of data that was sent by the sender(1326 bytes)
is received by the client(4+1322)
, there is an extra call to the read(ByteBuffer src)
is made which ends of reading 0 bytes. My (ill informed) guess was that was some kind of an EOF indicator, but from the comments on the question it looks like that has to do something with how the application itself goes about reading data from the channels.
No it doesn't.
Forget about what's underneath. You are using
java.nio.channels.SocketChannel
.You don't. You send the contents. The sending
ByteBuffer[]
array is gathered into a byte stream and sent as bytes.No it doesn't. The received bytes are scattered into another
ByteBuffer[]
array, if that's what you use to read the channel. If you use gather-write and scatter-read there is no relationship between the sending and receivingByteBuffer
arrays other than the actual bytes received.No.
It doesn't. It receives a byte stream, into an array of
ByteBuffers
that it provided itself.This doesn't begin to make sense.
ByteBuffers
are neither send nor received, either individually or as arrays.There is no example here, only some output. An example would be useful but it would have to consist of Java code.
Can we assume this should be
SocketChannel.read(ByteBuffer[] srcs)
? It doesn't make sense otherwise.This can only mean two things:
read(ByteBuffer src)
and called it three times; the peer had only sent 1326 bytes; so the third read returned zero, meaning no data was available to be read.OR
read(ByteBuffer[] srcs)
, wheresrcs
contained threeByteBuffers
: one of length exactly 4, one of length >= 1322, and one of length > 0; only 1326 bytes were received, so the thirdByteBuffer
was cleared, or unaffected.There is no such call, unless you made it, and if you made it when there was no data available to be read you got zero bytes. Why is this surprising?
No. End of stream is signalled by
read()
returning -1.Correct. You tried to read beyond the end of the data that was sent, or with more
ByteBuffers
than were required to hold the data that was received. Simple as that.