15

I am working on writing a network application in C++ on the Linux platform using the typical sockets API, and I am looking at 2 alternative ways of writing a byte array to a TCP stream: either by calling write(), or by calling send(). I know that, since this is Linux, the socket handle is simply a file descriptor, and therefore it is valid to perform read() and write() calls on the socket, however the sockets API also provides the send() and recv() functions to perform the same tasks.

I am therefore wondering if there is any particular reason to choose one class of functions over the other - are the send/recv functions optimized for network writing/reading, do they perform better, etc? Or is it really arbitrary which functions I use? Do read() and write() behave properly in all cases?

Thanks for any insights!

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
rmrobins
  • 435
  • 2
  • 5
  • 6

3 Answers3

22

There should be no difference. Quoting from man 2 send:

The only difference between send() and write() is the presence of flags. With zero flags parameter, send() is equivalent to write().

So long as you don't want to specify and flags for send() you can use write() freely.

Nathan Fellman
  • 122,701
  • 101
  • 260
  • 319
  • Is this true of FreeBSD or other platforms as well? - that line does not appear in my send(2) man page. – Good Person Mar 18 '14 at 23:34
  • @GoodPerson It applies to all platforms. If that were not so, `inetd` and the like would not work. (`inetd` dups your socket into your daemon process's stdin and stdout, and your process can interact directly with stdin and stdout in the normal way, without any awareness that they are sockets. Of course, you can do socket stuff with them too.) – C. K. Young Nov 29 '14 at 06:43
7

recv and send allow you to specify flags, such as for out-of-band packets. If you don't need to specify the flags, read and write are perfectly adequate.

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
1

write v.s. send for a single byte, or a single array probably won't be much different - they will soon end up the same code path (ultimately they perform the same operation). The overhead in network transmission is highly unlikely to be at that level; it will the actual TCP connection and moving the bits over wires.

However, if you are intending to send large, multipart messages in a single go you should look at the sendmsg() syscall - this allows you to specify a list of non-contiguous arrays of data to send.

At the end of the day the normal guidelines apply - write the application first, then benchmark to see where your bottlenecks are.

DaveR
  • 9,540
  • 3
  • 39
  • 58