2014-05-05 31 views
0

我通过TCP协议从Windows套接字接收数据。为此,我使用阻止recv()。我的问题是:当操作系统(OS)允许读取tcp缓冲区 (从tcp的角度来看)?操作系统在接收到的数据上发送ACK后会发生吗?当recv返回?

回答

1

对于你应该查看TCP接收作为由两个独立的过程中所有的实际目的:

  • 的OS接收到TCP数据和ACK的它的另一侧,将其存储在内部内核缓冲区,这不是可访问的对您的过程
  • 当你recv或任何等效的系统调用,操作系统拷贝从其内部缓冲区的用户空间缓冲区中的数据

一旦TCP收到是在窗口数据,并传递ç hecksums和所有,对方不能背弃它。这意味着它在读取数据之前还是之后发送ACK并不重要。另外,操作系统可能需要再次确认(例如,如果ACK丢失)。因此,确认数据的时间与你从套接字读取(广告窗口)无关。

由此得到的结果是你在做recv对连接没有影响。您可以将套接字缓冲区中的recv看作是一个奇妙的memcpy到您的应用程序缓冲区。

+0

假设TCP接收数据并且ACK还没有发送:在这种情况下recv可能会从缓冲区读取数据,或者它会等到发送ACK为止? –

+0

它没有任何区别。数据已经到达:您可以阅读它。 – EJP

0

从您的应用程序中随时可以拨打recv。如果套接字阻塞,则在TCP内部接收缓冲区中存在一些数据之前,recv不会返回。

如果对端发送某些数据,TCP堆栈应负责发送ACK。调用recv现在会导致数据从TCP堆栈的缓冲区复制到传递到'recv`的缓冲区。

正如@cnicutar在另一个答案中指出的那样,即使您不呼叫recv TCP也会发送ACK以保持连接健全。应用程序可以调用recv,将数据存入缓冲区,从而导致TCP缓冲区被刷新。另一个recv不会给你相同的数据。