繁体   English   中英

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

[英]Weird behavior of send() and recv()

抱歉英语不好

为什么如果我在服务器上有两个send() -s,在客户端有两个recv() -s,有时第一个recv()会从服务器获取第二个send()的内容,而不只是获取内容第一个并让另一个recv()获取另一个send()的“应有的和适当的”内容?

我怎样才能以其他方式获得这项工作?

这是设计使然。

TCP 流是可以在两个端点之间发送字节的通道,但传输是基于流的,而不是基于消息的。

如果你想发送消息,那么你需要对它们进行编码......例如,通过预先设置一个“大小”字段,该字段将通知接收者期望正文的字节数。

如果您先发送 100 个字节,然后再发送其他 100 个字节,则接收器很可能会在两个不同的读取命令中一次看到 200 个,甚至 50 + 150 个。 如果您想要消息边界,那么您必须自己将它们放入数据中。

有一个较低的层(数据报)允许发送消息,但是它们的大小有限并且无法保证交付(即消息可能会丢失,会重复或您发送的两条消息将以不同的方式到达命令)。 TCP 流建立在此数据报服务之上,并实现了在两个端点之间可靠传输数据所需的所有逻辑。

作为替代方案,有一些旨在提供端点之间可靠消息传递的库,例如ZeroMQ

很可能您使用 SOCK_STREAM 类型的套接字。 这是一个 TCP 套接字,这意味着您将数据推送到一侧,它以相同的顺序从另一侧获取,并且不会丢失块,但没有分隔符。 所以send()只是发送数据,而recv()接收当前时刻可用的所有数据。

您可以使用 SOCK_DGRAM,然后将使用 UDP。 但在这种情况下,每个send()都会发送一个数据报,而recv()会接收它。 但是你不能保证你的数据报不会被打乱或丢失,所以你必须自己处理这些问题。 最大数据报大小也有限制。

或者您可以坚持使用 TCP 连接,但您必须自己发送分隔符。

暂无
暂无

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

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