TCP关闭连接——不容易

(1)内核收到rst后,会立即释放TCP连接占用的内存资源(状态、数据)和端口号。

(2)应用层收到rst后,第一次读取,读取返回-1,errno设置为ECONNRESET。POLLIN会立即再次触发,然后read会返回0。

(3)应用层收到rst后,第一次写。(此时,写操作返回一个e-EPIPE错误。)内核向进程发送一个SIGPIPE信号。该信号的默认行为是终止进程,因此进程必须捕获它,以避免被不情愿地终止。

为此,只有两种情况会关闭TCP连接:

(1)RST,相当于复位。

(2)关闭本地写(即发送FIN段),但不能主动关闭对等写,即只能主动关闭一半的连接,另一个方向的连接由对等主动关闭。

(3)如果本端接收到对端的FIN段(即read返回0),则无法判断对端是关闭(对端已经停止读取)还是关闭(对端还能读取,而且是半关闭)。

问:那么这个时候,如果我们再去wirte会怎么样?

1.客户端可能调用close (CFD,close _ wr),也就是单向关闭它的写终端,所以我读成0。在这种情况下,我不想立即关闭这个连接,但我会在给这个客户端写完所有回复后关闭它。

2.客户可以要求成交(cfd)。此时,如果我写(sfd,buf2,size2),我将返回一个EPIPE错误。

问:read返回0怎么办?

此时是否关闭取决于您的应用程序。一般来说,如果对方叫关,那么你也可以关。否则,你不能关闭。比如对方给你发一个包,关机写,然后调用recv。这时,你也可以退回一个或多个包裹。连接处于半封闭状态,可以永远持续下去。摘自知乎胡宇光。

问:fin _ wait 2和CLOSE_WAIT的状态会一直持续下去吗?

涉及

/infuq/others/yyvoa7#cDrZq

/huangyimo/文章/详情/81297805

/QQ _ 35733751/文章/详情/80146161

补充面试问题

1.如何避免TCP(高并发)的TIME_WAIT状态