简体   繁体   English

send() 和 recv() 的奇怪行为

[英]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() ?为什么如果我在服务器上有两个send() -s,在客户端有两个recv() -s,有时第一个recv()会从服务器获取第二个send()的内容,而不只是获取内容第一个并让另一个recv()获取另一个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. TCP 流是可以在两个端点之间发送字节的通道,但传输是基于流的,而不是基于消息的。

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.如果您先发送 100 个字节,然后再发送其他 100 个字节,则接收器很可能会在两个不同的读取命令中一次看到 200 个,甚至 50 + 150 个。 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. TCP 流建立在此数据报服务之上,并实现了在两个端点之间可靠传输数据所需的所有逻辑。

As an alternative there are libraries designed to provide reliable message-passing between endpoints, like ZeroMQ .作为替代方案,有一些旨在提供端点之间可靠消息传递的库,例如ZeroMQ

Most probably you use SOCK_STREAM type socket.很可能您使用 SOCK_STREAM 类型的套接字。 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.这是一个 TCP 套接字,这意味着您将数据推送到一侧,它以相同的顺序从另一侧获取,并且不会丢失块,但没有分隔符。 So send() just sends data and recv() receives all the data available to the current moment.所以send()只是发送数据,而recv()接收当前时刻可用的所有数据。

You can use SOCK_DGRAM and then UDP will be used.您可以使用 SOCK_DGRAM,然后将使用 UDP。 But in such case every send() will send a datagram and recv() will receive it.但在这种情况下,每个send()都会发送一个数据报,而recv()会接收它。 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.或者您可以坚持使用 TCP 连接,但您必须自己发送分隔符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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