LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Preventing socket from `splitting' into several packets? (https://www.linuxquestions.org/questions/programming-9/preventing-socket-from-%60splitting-into-several-packets-4175564179/)

Scraph 01-17-2016 11:04 AM

Preventing socket from `splitting' into several packets?
 
I am working with Linux sockets, TCP and/or UDP streams, and I'm trying to figure out how to prevent what I write() from being (seemingly) arbitrarily split into several smaller packets. The most I will ever transmit in one `chunk' is 4096 bytes.

When I write() the entire 4096 byte buffer in one go, it appears that I receive 2 packets of 2896 bytes and 1200 bytes separately on the other end ... So, I try to split it up into 2 2048 byte calls to write(). I appear to get on the other end 2048 bytes, 1448 bytes, and 600 bytes. If I split it into 4 1024 byte calls to write() then I get 1024, 1024, 1024, 848, and 176 bytes ... only very rarely have I seen it make it through as 4 equally sized packets.

What is insisting on splitting the last packet into 2 oddly sized packets? How can I enforce that a chunk of data is actually maintained in a single packet?

Ideally, I need the 4096 bytes that I transmit to arrive at the other end as a single 4096 byte packet, every single time.

NevemTeve 01-17-2016 11:56 AM

There's no pockets in TCP, it is a byte-stream. If you want data-units, you have do it yourself, for example: before the actual data-unit send the length of the data-unit in 4 bytes (say, network byte-order).

Scraph 01-17-2016 12:17 PM

TCP abstracts to `byte-stream' as far as the end-user is concerned ... but TCP still transmits in segments which are packaged up into IP packets... so TCP segmentation certainly exists.

Are you trying to tell me there is no programmatic way to control/influence TCP segmentation?

teapottwo 01-17-2016 12:24 PM

According my book (old now), the max size of IPV4 datagram is 65535 bytes (65575 bytes for IPV6) (*both including headers), however the MTU of Ethernet is 1500 bytes, but it depends on the route taken across a network since the protocol will use the lowest MTU of all the hardware it crosses, known as the "path MTU".

There is the DF bit flag, "Don't Fragment", but if the "path MTU" is lower then you'll get the "destination unreachable" error.
Supposedly IPV6 doesn't fragment, but again due to path may produce the "packet too big error".


Setting of the DF flag will depend on what library / level you are using...



MTU = Maximum Transmission Unit

NevemTeve 01-18-2016 03:58 AM

Term 'byte stream' means byte-stream: bytes sent together might received separately; and vice versa.
Mind you, no byte will be lost, and the order of bytes won't change. (Of course connection-loss is possible).

Scraph 01-18-2016 08:30 AM

Yeah, the MTU of Ethernet is lower than TCP/IP allowed segments/packets ... but the IP protocol itself would have to handle fragmentation of its own datagrams, if the physical/hardware layers were to cause it. After all, UDP datagrams still guarantee that a single write() command will always be received on the other end by a single read() command (if received at all, of course).

In reading the socket man page and other articles on the subject, I find that I'm really just wishing that `SOCK_SEQPACKET' was supported on TCP/IP. That's pretty much what I've found I was asking for ... sequenced, reliable, two-way, connection-based _datagrams_.

On further thought, my application can stand a few lost or out-of-order packets so I'll just go to SOCK_DGRAM.

teapottwo 01-18-2016 10:10 AM

Quote:

Originally Posted by Scraph (Post 5480294)
After all, UDP datagrams still guarantee that a single write() command will always be received on the other end by a single read() command (if received at all, of course).

Fragmentation rules still apply to UDP.


All times are GMT -5. The time now is 07:47 PM.