简体   繁体   中英

Weird behavior of send() and recv()

SORRY FOR BAD ENGLISH

Why if I have two send() -s on the server, and two recv() -s on the client, sometimes the first recv() will get the content of the 2nd send() from the server, without taking just the content of the first one and let the other recv() to take the "due and proper" content of the other send() ?

How can I get this work in an other way?

This is by design.

A TCP stream is a channel on which you can send bytes between two endpoints but the transmission is stream-based, not message based.

If you want to send messages then you need to encode them... for example by prepending a "size" field that will inform the receiver how many bytes to expect for the body.

If you send 100 bytes and then other 100 bytes it's well possible that the receiver will instead see 200 at once, or even 50 + 150 in two different read commands. If you want message boundaries then you have to put them in the data yourself.

There is a lower layer (datagrams) that allows to send messages, however they are limited in size and delivery is not guaranteed (ie it's possible that a message will get lost, that will be duplicated or that two messages you send will arrive in different order). TCP stream is built on top of this datagram service and implements all the logic needed to transfer data reliably between the two endpoints.

As an alternative there are libraries designed to provide reliable message-passing between endpoints, like ZeroMQ .

Most probably you use SOCK_STREAM type socket. This is a TCP socket and that means that you push data to one side and it gets from the other side in the same order and without missing chunks, but there are no delimiters. So send() just sends data and recv() receives all the data available to the current moment.

You can use SOCK_DGRAM and then UDP will be used. But in such case every send() will send a datagram and recv() will receive it. But you are not guaranteed that your datagrams will not be shuffled or lost, so you will have to deal with such problems yourself. There is also a limit on maximal datagram size.

Or you can stick to TCP connection but then you have to send delimiters yourself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM