如果recv()接收到有效负载大小为0的有效TCP数据包,它将返回什么值

如果recv()接收到有效负载大小为0的有效TCP数据包,它将返回什么值,tcp,recv,Tcp,Recv,在TCP套接字编程中,如果recv()返回0,则表示另一端已关闭其连接。但是,恕我直言,TCP RFC并不要求TCP的有效负载大于0。因此,理论上,TCP堆栈可以接收有效负载为0的消息 因此,本质上我的问题是,如果接收到一个负载大小为0的数据包,recv()将返回什么?如果它返回0,那么我们如何区分它与关闭连接指示。对,根据POSIX,如果recv返回0,则对等方将正确关闭连接 如果有人成功地发送了一个负载为零的TCP数据包,那么OS就不必向该套接字上的recv系统调用上被阻止的进程返回任何数据

在TCP套接字编程中,如果
recv()
返回0,则表示另一端已关闭其连接。但是,恕我直言,TCP RFC并不要求TCP的有效负载大于0。因此,理论上,TCP堆栈可以接收有效负载为0的消息


因此,本质上我的问题是,如果接收到一个负载大小为0的数据包,
recv()
将返回什么?如果它返回0,那么我们如何区分它与关闭连接指示。

对,根据POSIX,如果
recv
返回
0
,则对等方将正确关闭连接

如果有人成功地发送了一个负载为零的TCP数据包,那么OS就不必向该套接字上的
recv
系统调用上被阻止的进程返回任何数据


请记住,TCP有效负载形成一个连续的流,可以由操作系统随机切片,而不是在单个系统调用期间必须返回的数据报序列。

有效负载大小为0的TCP段无处不在-它们几乎出现在每个实际TCP流中。当一方希望确认从另一方接收到数据,但自己没有数据要发送时,就会发送它们。(这些通常称为“ACK数据包”,但“ACK数据包”只是碰巧不包含数据的常规段)

由于此类数据包不包含任何要传递给用户应用程序的数据,因此它们不会导致
recv()
返回-
recv()
将继续阻塞,直到一些实际数据到达。如果
recv()
返回0,则明确表示另一端已关闭其连接端,不再发送任何数据


请记住,TCP是面向流的:单个
recv()
调用返回的数据与单个TCP段中的数据之间存在一对一的映射。单个
recv()
调用可能返回与多个TCP段重叠的数据块,单个TCP段中的数据可能在多个
recv()
调用中返回。TCP段之间的边界对于使用BSD套接字API的应用程序不可见。如果您想要这样的边界,您需要在TCP流中使用应用层协议来实现自己,或者使用面向数据报的协议,如UDP。

ACK数据包将设置ACK标志。@AlastairG:对,但是除了初始的
SYN
或连接重置之外的每个数据包都设置了
ACK
位。是,没错,我忘了:)我不确定他们一定要这么做,这只是一种良好的做法。