2

I have a simple client which accepts a single uint32_t from the server through a socket. Using the solution that appeared here many times (e.g. transfer integer over a socket in C) seems to work, but:

When calling "read" on files I know that the system is not guaranteed to read the entire content of the message at once, and it therefore returns the number of bytes read. Couldn't the same happen when accepting 4 bytes over a network socket?

If this can't happen, why is that? and if it can, how is it possible to make sure the send is "atomic", or is it necessary to piece back the bytes myself?

Nescio
  • 513
  • 4
  • 13

3 Answers3

3

Depending on the socket type, different protocols can be used. SOCK_STREAM (correspond to TCP on network sockets) is a stream oriented protocol, so packets may be re-combined by the sender, the receiver or any equipement in the middle.

But SOCK_DGRAM (UDP) or SOCK_SEQPACKET actually send packets that cannot be changed. In that case 4 bytes in the same packet are guaranteed be be available in the same read operation, except if the receive buffer is too small. From man socket:

If a message is too long to fit in the supplied buffer, excess bytes may be discarded depending on the type of socket the message is received from

So if you want to have atomic blocs, use a packet protocol and not a stream one, and make sure to have large enough receive buffers.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
1

If the underlying protocol is TCP/IP, which is stream-oriented (there are no "packets" or "messages", just two byte streams), then yes.

You need to take care to manage the amount of read data so that you can know where each "message" (in your case, a single integer) begins and ends.

unwind
  • 391,730
  • 64
  • 469
  • 606
1

When calling "read" on files I know that the system is not guaranteed to read the entire content of the message at once

That is wrong, if the requested number of bytes is available they are read:

POSIX read manual says: The value returned may be less than nbyte if the number of bytes left in the file is less than nbyte

This is at least correct for regular files, for pipes and alike it is a different story.

Couldn't the same happen when accepting 4 bytes over a network socket?

(I suppose you are talking about TCP sockets.) That may happen with socket because underlying protocol may transport your byte in any suitable manner (read about TCP fragmentation for example), the only thing ensured is that if received bytes are received in the same order that they have been sent. So, to read a given number of bytes you have to try to read those bytes eventually with several reads. This is usually made by looping over the read until needed bytes are received and read.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69