On Linux (Kernel 3.0.0.12; C++ with GCC 4.6.1) I want to send shortly after each other a few TCP-packets via (POSIX) send-call.
With Wireshark I can see that the packets weren't sent in separate TCP-frames, but two or more were sent together in one packet.
Is there any way to tell the system to send data from one send()
-buffer in own TCP-packet? The programmflow shouldn't block at the send-call.
Your TCP stack is implementing Nagle's algorithm trying to increase efficiency by buffering data. Its a common optimization where the intent is amortize the cost of the 40+ byte (TCP + IP) header. Instead of sending multiple small packets, the stack buffers the data and combines them into a larger packet thereby reducing the header overhead.
TCP stacks don't buffer indefinitely though. As long as there is some un-acknowledged sent data on the connection, the sender continues to buffer. The next packet is sent out when:
- A full packet worth of data is available to be sent OR
- All previously sent data is acknowledged by the receiver
You can usually disable this by setting the TCP_NODELAY
socket option.
setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
If you want each packet to be sent individually, consider using UDP. You will however have to implement your own error detection and retransmission of dropped packets, etc...
You can turn off Nagle, but it'd be better to stop fighting the TCP stack. It's better to add some form of framing to your protocol, so you don't need to worry about whether your transmission units have been aggregated and/or split.
In the sender, this generally means using termination characters or giving lengths.
In the receiver, it means knowing how to read up to some termination character, and/or knowing how to use part of a received transmission unit or assemble a complete message from multiple transmission units.
I like to do this with bufsock, though it's very much a Python technology. But you likely want something similar for C++:
http://stromberg.dnsalias.org/~strombrg/bufsock.html
"packet".
And no, that's the whole point of having a "network stack" - your Ethernet frames can be transmitted and routed independently of higher levels of the TCP/IP stack. You totally don't WANT to micro-manage this!