views:

530

answers:

1

When using SocketChannel, you need to retain read and write buffers to handle partial writes and reads.

I have a nagging suspicion that it might not be needed when using a DatagramChannel, but info is scarce.

What is the story?

Should I call (non-blocking) receive(ByteBuffer) repeatedly until I get a null back to read all waiting datagrams?

When sending in non-blocking mode, can I rely on send(ByteBuffer, SocketAddress) to either send the the whole buffer or rejecting it entirely, or do I need to possibly keep partially written buffers?

+1  A: 

Every read of a Datagram is the entire datagram, nothing more, nothing less. There's a hint that this is the case in the description of java.nio.DatagramChannel.read:

If there are more bytes in the datagram than remain in the given buffers then the remainder of the datagram is silently discarded

When you're dealing with a SocketChannel, it's a message stream; there's no guarantee how much or how little data you'll get on each read, as TCP is reassembling separate packets to recreate the message from the other side. But for UDP (which is what you're reading with the DatagramChannel) each packet is its own atomic message.

Jared Oberhaus
What about writes though? Will there ever be partial writes due to the outgoing buffer being full, or is that an all-or-nothing affair as well?
Nuoji
That is also all or nothing. If you try to write something that's bigger than a datagram, I'm not sure what will happen (exception?), but it will certainly not be sent. Note that you have almost 64k for a single UDP datagram.
Jared Oberhaus
Another couple notes: There is no guarantee a datagram is delivered on the other end, but usually they will be delivered. Also, Windows does not seem to be able to send a broadcast UDP datagram that exceeds the MTU of the network, so watch out for that.
Jared Oberhaus