gimmeamilk
gimmeamilk

Reputation: 2110

Linux: send whole message or none of it on TCP socket

I'm sending various custom message structures down a nonblocking TCP socket. I want to send either the whole structure in one send() call, or return an error with no bytes sent if there's only room in the send buffer for part of the message (ie send() returns EWOULDBLOCK). If there's not enought room, I will throw away the whole structure and report overflow, but I want to be recoverable after that, ie the receiver only ever receives a sequence of valid complete structures. Is there a way of either checking the send buffer free space, or telling the send() call to do as described? Datagram-based sockets aren't an option, must be connection-based TCP. Thanks.

Upvotes: 5

Views: 2578

Answers (2)

Nemo
Nemo

Reputation: 71515

Linux provides a SIOCOUTQ ioctl() to query how much data is in the TCP output buffer:

http://www.kernel.org/doc/man-pages/online/pages/man7/tcp.7.html

You can use that, plus the value of SO_SNDBUF, to determine whether the outgoing buffer has enough space for any particular message. So strictly speaking, the answer to your question is "yes".

But there are two problems with this approach. First, it is Linux-specific. Second, what are you planning to do when there is not enough space to send your whole message? Loop and call select again? But that will just tell you the socket is ready for writing again, causing you to busy-loop.

For efficiency's sake, you should probably bite the bullet and just deal with partial writes; let the network stack worry about breaking your stream up into packets for optimal throughput.

Upvotes: 4

Aaron Digulla
Aaron Digulla

Reputation: 328556

TCP has no support for transactions; this is something which you must handle on layer 7 (application).

Upvotes: 1

Related Questions