C socket:确实发送等待recv结束?

我在Windows上使用阻塞C套接字。 我使用它们将数据的更新从服务器发送到客户端,反之亦然。 我以高频率(每100毫秒)发送更新。 send()函数是否会等待收件人recv()在结束之前接收数据?

如果我理解man手册页,我会假设:

“send()的成功完成并不能保证传递信息。”

那么,如果一个运行10个send()而另一个只有完整的1个recv()什么?

我是否需要使用某种确认系统?

让我们假设您正在使用TCP。 当您调用send时,您发送的数据会立即放在传出队列上,然后发送成功完成。 但是,如果send无法将数据放在传出队列中,send将返回错误。

由于Tcp是保证传送协议,因此只有在远程端收到确认后,才能删除传出队列上的数据。 这是因为如果没有及时收到确认,则可能需要重新发送数据。

如果远程端缓慢,则传出队列将填满数据,然后发送将阻塞,直到有空间将新数据放在传出队列上。

然而,连接失败的方式是无法再发送任何其他数据。 虽然TCP连接一旦关闭,任何进一步的发送都将导致错误,用户无法知道实际上有多少数据到达另一方。 (我知道无法从套接字检索TCP簿记到用户应用程序)。 因此,如果需要确认收到数据,您应该在应用程序级别实现此function。

对于UDP,我认为不言而喻,某种方式报告已收到或未收到的内容是必须的。

send()阻塞,直到操作系统(内核)获取数据并将其放入传出数据的缓冲区。 它不会等到另一端收到数据。

如果您通过TCP发送,则可以保证交付1 ,另一端将按照发送的顺序接收数据。 但是,这可能会合并在一起,因此您发送的10个单独更新可以作为单个大数据包接收(反之亦然 – 单个更新可以在任意数量的数据包中分解)。 这意味着,除其他事项外,任何数据的任何ACK都隐含地确认收到所有先前的数据。

如果您正在使用UDP,那么这些都不是真的 – 数据可能无序到达,或者被丢弃而根本不会被传送。 如果您关心所有收到的数据,您只需要在UDP本身之上构建自己的某种确认系统。

1当然,保证有一个限制 – 如果网络电缆被切断(或其他)数据包将无法传送,但您至少会收到一条错误消息,告诉您连接已丢失。

如果您正在使用TCP,则可以免费获得确认,因为这是协议所做的一部分。 但听起来像这种类型的应用程序,你可能想要使用UDP。 在任何一种情况下,尽管send()在客户端成功recv()之前不会阻塞。

如果客户端收到每条消息至关重要,那么使用TCP。 如果客户端可以错过一条或多条消息,则使用UDP。

TCP保证在较低的TCP堆栈级别交付。 它重试传递,直到接收部分确认收到数据,但您的应用程序可能永远不知道该事实。

假设您正在发送数据块,并且需要根据某些逻辑将这些数据块放在某处。 如果您的应用程序不准备知道每个块必须放在哪里,那么在TCP级别接收它可能是没用的。 原帖是关于应用程序级逻辑的。