使用TCP关闭(sock,SHUT_RD)的行为

Cla*_*diu 10 sockets networking network-programming tcp

使用TCP套接字时,有什么用呢

shutdown(sock, SHUT_RD);
Run Code Online (Sandbox Code Playgroud)

实际上呢?是否只是让所有recv()调用都返回错误代码?如果是这样,哪个错误代码?

它是否会导致底层TCP连接发送任何数据包?对方在此时发送的任何数据会发生什么 - 它是否保留,并且连接的窗口大小一直在缩小,直到达到0,或者它是否被丢弃,窗口大小不会缩小?

Chr*_*ung 5

查看 Linux 源代码,shutdown(sock, SHUT_RD)似乎不会对套接字造成任何状态更改。(显然,需要设置shutdown(sock, SHUT_WR)原因FIN。)

我无法评论窗口大小的变化(或缺乏变化)。不过你可以写个测试程序看看。只需让您inetd运行一项chargen服务,然后连接到它即可。:-)


Tom*_*Tom 5

关闭套接字的读取端将导致任何阻塞的recv(或类似的)调用返回0(指示正常关机)。我不知道当前在IP堆栈上传输的数据将如何处理。毫无疑问,它将忽略来自另一方的动态数据。它根本不会影响对该套接字的写入。

实际上,明智地使用shutdown是确保完成后立即清理的一个好方法。不使用keepalive的HTTP客户端可以在发送请求完成后立即关闭写端,看到的服务器也Connection: closed可以在接收到请求后立即关闭读端。这将立即导致任何进一步的错误活动,这在编写协议级代码时非常有用。


sac*_*cha 5

shutdown(,SHUT_RD) 在 TCP 协议中没有任何对应物,因此当有人写入连接而另一端表示它不会读取或当您在声明后尝试读取时,这几乎取决于实现如何表现你不会。

在稍微低一点的层面上,记住 TCP 连接是一对流,使用它们发送数据直到它们声明它们完成(通过发送 FIN 的 SHUT_WR)。并且这两个流程是非常独立的。


use*_*421 5

它有两种效果,其中之一与平台相关。

  1. recv()将返回零,表示流结束。
  2. 对等方对连接的任何进一步写入将要么 (a) 被接收方默默地丢弃 (BSD),(b) 被接收方缓冲并最终导致send()阻塞或返回 -1/ EAGAIN/EWOULDBLOCK(Linux),或者 (c ) 导致接收方发送 RST (Windows)。


小智 5

shudown(sock,SHUT_RD)我在 Ubuntu 12.04 上测试。我发现,当您调用时,shutdown(sock,SHUT_RD)如果 TCP 缓冲区中没有任何类型的数据(包括 FIN....),则连续的读取调用将return 0(指示流结束)。但是,如果有一些数据在关闭函数之前或之后到达,则读取调用将正常处理,就像未调用关闭函数一样。似乎shutdown(sock,SHUT_RD)不会导致任何 TCP 状态更改为套接字