send()
函数发送数据时,是否会等待接收方recv()
接收数据才结束?如果我理解手册正确的话,我认为不会:
"send()的成功完成不能保证消息传递。"
那么,如果一个人运行10个
send()
调用,而另一个人只完成了1个recv()
,会发生什么?我需要使用某种确认系统吗?
send()
函数发送数据时,是否会等待接收方recv()
接收数据才结束?send()
调用,而另一个人只完成了1个recv()
,会发生什么?假设您正在使用TCP协议。当您调用send时,发送的数据将立即放置在出站队列中,并且send操作将成功完成。但是,如果send无法将数据放置在出站队列中,则会返回错误。
由于TCP是一种保证交付的协议,只有在远程端确认接收到数据后,出站队列中的数据才能被删除。这是因为如果在规定时间内没有收到确认消息,则可能需要重新发送数据。
如果远程端响应缓慢,则出站队列将填满数据,而send操作将阻塞直到有空间将新数据放置在出站队列中。
然而,连接可能会以无法再发送任何进一步数据的方式失败。尽管一旦TCP连接已关闭,任何进一步的发送都将导致错误,但用户无法知道有多少数据实际上已经传输到另一端。(我不知道如何从套接字中检索TCP簿记到用户应用程序)。因此,如果需要确认数据的接收,您应该在应用程序级别上实现此功能。
对于UDP协议,可以毫不费力地说必须报告已经或未收到的数据。
send()
会阻塞,直到操作系统(内核)将数据放入传出数据缓冲区中。它不会等待另一端接收数据。
如果你使用UDP协议,上述情况都不适用——数据可能会乱序到达,或者根本就会丢失。如果你关心所有的数据都能被接收,那你几乎需要在UDP之上构建自己的确认系统。
1当然,对于保证的限制也有一个限度——如果网络电缆被切断(或其他原因),数据包将无法传递,但你至少会收到一个错误消息告诉你连接已经丢失。
如果您正在使用TCP,则可以免费获得确认,因为这是协议在幕后执行的一部分。但是对于这种类型的应用程序,您可能希望使用UDP。无论哪种情况,send()
都不会阻塞,直到客户端成功recv()
。
如果客户端接收每条消息至关重要,则使用TCP。如果客户端错过一条或多条消息没有问题,则使用UDP。
TCP在较低的TCP协议栈层面上保证传递。它会重试传递,直到接收方确认已经接收到数据,但是您的应用程序可能永远不会知道这个事实。
假设您正在发送数据块,并且需要根据某些逻辑将这些数据块放置在某个位置。如果您的应用程序没有准备好知道每个单独块应该放置在哪里,那么在TCP层面接收它可能是无用的。原始帖子是关于应用程序级别的逻辑。