如果接收到有效负载大小为 0 的有效 TCP 数据包,recv() 将返回什么值 [英] What value will recv() return if it receives a valid TCP packet with payload sized 0

查看:24
本文介绍了如果接收到有效负载大小为 0 的有效 TCP 数据包,recv() 将返回什么值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在TCP套接字编程中,如果recv()返回0,则认为对方关闭了连接.但是,AFAIK,TCP RFC 并没有要求 TCP 的有效载荷 > 0.因此,理论上,TCP 堆栈可以接收有效载荷为 0 的消息.

In TCP socket programming, if recv() returns 0, it is taken as an indication that the other side closed its connection. However, AFAIK, the TCP RFC does not mandate the payload of TCP to be > 0. So, theoretically, a TCP stack can receive a message with payload 0.

所以,本质上我的问题是,如果 recv() 收到一个有效载荷大小为 0 的数据包,它会返回什么?如果它返回 0,那么我们如何将它与关闭的连接指示区分开来.

So, essentially my question is what will recv() returns if it receives a packet of payload sized 0? If it returns 0, then how do we distinguish it from a closed connection indication.

推荐答案

有效载荷大小为 0 的 TCP 段无处不在 - 它们几乎出现在每个现实世界的 TCP 流中.每当一方希望确认收到来自另一方的数据,但没有自己的数据要发送时,就会发送它们.(这些通常称为ACK 数据包",但ACK 数据包"只是一个恰好不包含数据的常规段).

TCP segments with a payload size of 0 are ubiquitous - they occur in pretty much every real-world TCP stream. They're sent whenever one side wishes to acknowledge reciept of data from the other, but has no data to send of its own. (These are commonly known as "ACK packets", but an "ACK packet" is just a regular segment that happens to contain no data).

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

Since such packets do not contain any data to deliver to the user application, they will not cause recv() to return - recv() will continue blocking until some actual data arrives. If recv() returns 0, then it is a definite indication that the other end has closed its side of the connection and won't be sending any more data.

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

Remember that TCP is stream-oriented: there is not a 1-to-1 mapping between the data returned by a single recv() call and the data in a single TCP segment. A single recv() call might return a block of data that overlaps several TCP segments, and the data in a single TCP segment might be returned in multiple recv() calls. The boundaries between TCP segments are not visible to the application using the BSD sockets API. If you want such boundaries, you need to either implement yourself using an application-layer protocol within the TCP stream, or use a datagram-oriented protocol like UDP.

这篇关于如果接收到有效负载大小为 0 的有效 TCP 数据包,recv() 将返回什么值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆