使用TCP套接字时,
是什么shutdown(sock, SHUT_RD);
实际上呢?是否仅使所有recv()
次调用返回错误代码?如果是这样,哪个错误代码?
是否会导致底层TCP连接发送任何数据包?对方在此时发送的任何数据会发生什么 - 它是否保留,连接的窗口大小是否一直缩小,直到达到0,或者它是否被丢弃,窗口大小不会缩小?
答案 0 :(得分:4)
关闭套接字的读取端将导致任何阻塞的recv
(或类似)调用返回0
(表示正常关闭)。我不知道当前在IP堆栈上传输的数据会发生什么。它肯定会忽略来自另一方的数据。它根本不会影响对该套接字的写入。
事实上,明智地使用shutdown
是确保您在完成后立即清理的好方法。不使用keepalive的HTTP客户端可以在发送请求后立即关闭写入端,看到Connection: closed
的服务器也可以在收到后立即关闭读取端。请求。这将导致任何进一步的错误活动立即显而易见,这在编写协议级代码时非常有用。
答案 1 :(得分:3)
shutdown(,SHUT_RD)在TCP协议中没有任何对应物,所以当有人写入一个连接时,如果有人写入另一方表示它将无法读取或当您尝试读取后,它几乎可以实现你宣称你不会。
在略低的级别上,记住TCP连接是一对流,使用对等方发送数据直到它们声明它们已完成(通过发送FIN的SHUT_WR)是有益的。这两个流程是相当独立的。
答案 2 :(得分:2)
查看Linux源代码,shutdown(sock, SHUT_RD)
似乎不会导致套接字状态发生任何变化。 (显然,shutdown(sock, SHUT_WR)
会导致设置FIN
。)
我不能评论窗口大小的变化(或缺少)。但你可以写一个测试程序来看。只需让inetd
运行chargen
服务,然后连接即可。 : - )
答案 3 :(得分:1)
我在Ubuntu 12.04上测试shudown(sock,SHUT_RD)
。我发现当你在TCP缓冲区中没有任何类型的数据(包括FIN ....)时调用shutdown(sock,SHUT_RD)
,连续的读取调用将return 0
(表示流的结束)。但是如果有一些数据在关闭函数之前或之后到达,则read调用将正常处理,就像没有调用shutdown函数一样。似乎shutdown(sock,SHUT_RD)
不会导致任何TCP状态更改为套接字
答案 4 :(得分:0)
shutdown(sock,SHUT_RD)导致套接字的任何写入器接收到sigpipe信号。
使用read系统调用的任何进一步读取将返回-1并将errno设置为EINVAL。
使用recv将返回-1并设置errno以指示错误(可能是ENOTCONN或ENOTSOCK)。
答案 5 :(得分:0)
它有两种效果,其中一种与平台有关。