TCP中shutdown函数/TCP套接字选项SO_LINGER来实现TCP优雅关闭

一 Shutdown函数

有时候,我们想给服务器发送一个FIN,告诉它们我们已经完成了数据发送,但是仍然保持套接字描述符打开以便读取。

这时候就需要一种关闭TCP连接其中一半的方法。

确切地说,close() / closesocket() 用来关闭套接字,将套接字描述符(或句柄)从内存清除,之后再也不能使用该套接字,与C语言中的 fclose() 类似。应用程序关闭套接字后,与该套接字相关的连接和缓存也失去了意义,TCP协议会自动触发关闭连接的操作。

shutdown() 用来关闭连接,而不是套接字,不管调用多少次 shutdown(),套接字依然存在,直到调用 close() / closesocket() 将套接字从内存清除。

调用 close()/closesocket() 关闭套接字时,或调用 shutdown() 关闭输出流时,都会在发送缓冲区中的数据发送完毕后向对方发送 FIN 包。FIN 包表示数据传输完毕,计算机收到 FIN 包就知道不会再有数据传送过来了。

 

Close函数的默认情况:

在套接字上不再发出发送或接收请求;套接字发送缓冲区中的内容被发送到对端。

如果描述符引用计数变为0,在发送完发送缓冲区中的数据后,跟以正常的TCP连接终止序列(发送FIN)。套接字接收缓冲区中的数据被丢弃。

Shutdown函数(SHUT_WR)

在套接字上不再发出发送请求;进程仍可从套接字接收数据;套接字发送缓冲区中的数据被发送到对端,后跟以正常的TCP连接终止序列(发送FIN),对套接字接收缓冲区无任何影响。

 

shutdown(shut_wr)实现优雅关闭的点在(自己总结的):

(1)close会关闭套接字2个方向的连接,即使对方还有数据需要发送或即使接收缓冲区中有数据未被处理。

而shutdown只关闭一个方向的连接,客户端还会收到对方发送的数据,接收缓冲区中的数据也会被处理。

(2)

close调用后通常立即返回(在发送完发送缓冲区的数据),很大可能在服务端读套接字接收缓冲区中的剩余数据前返回。对于服务器主机来说,服务器应用进程在读这些剩余数据之前就崩溃(会发送FIN)是完全可能的,而客户端应用进程不会知道。

后跟一个read调用的shutdown一直等到接收到了对端的FIN才返回。保证对方应用进程已成功读取接收缓冲区中的数据。且对方数据也发松完毕。

 

 

 

 

 

 

二 TCP套接字选项SO_LINGER

本选项指定close函数对面向连接的协议如何操作。

默认操作是close函数立即返回,如果有数据残留在发送缓冲区,系统会试着把这些数据发送给对端。

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章