tcp的close和shutdown

今天看到”Unix网络编程”第六章中半关闭连接, 对close和shutdown的功能区别产生了疑惑. 代码运行情况如下:

情况1:C(client)与S(server)建立链接之后, 当C向S发送数据之后调用shutdown来关闭写操作(断开链接的四次挥手中的前两次)告诉S, C端已发送数据完成, 此时S依然可向C发送数据.
情况2:C(client)与S(server)建议链接之后, 当C向S发送数据之后调用close来关闭socket(同样发送断开链接的四次挥手的前两次, 后两次挥手将由S端调用close来完成), 此时S端被其他条件阻赛并不调用close函数. 然后此时S端向C端发送数据将会引起C端回应rst数据包.

那么此时,情况1与情况2的socket状态机走到相同的地方, 所作的回应却完全不一样, 行为很令人奇怪.

在网上看了众多blog多后, 比较发现, close除了相当于C和S各发了shutdown之外, 还多了一个释放socket file descriptor的操作. 因此,猜测当调用close之后函数应该是瞬间返回的, 剩余的四次挥手以及TIME_WAIT状态应该是靠kernel来实现的, 那么就容易解释上述情况的原因了.

情况1:虽然调用了shutdown, 但是C依然拥有这个socket file descriptor, 因此算是半关闭链接, 情况2在调用close之后, C所拥有的socket file desciptor即被归还与kernel, 那么剩余的四次挥手及TIME_WAIT即由kernel来完成, 当此时S向C发送数据之后, kernel发现此socket file descriptor已经被释放, 即向S返回rst数据包.

以上均为猜测, 如找到相关文档再进行修正.



发表评论