Unix网络编程学习笔记——close与shutdown

在linux网络程序中有两个函数都可以发起终端TCP连接的请求,close与shutdown,那么这两个函数到底有什么区别呢?


int close(int sockfd);


close函数的缺省功能是将套接口做上”已关闭“标记,并立即返回到进程,这个套接字本身不能被该进程使用:它不能被用作read和write的参数,但TCP将试着发送以排队待发的任何数据,然后按照正常的TCP终止序列进行操作。close的缺省功能可以通过SO_LINGER套接口选项来改变。


close的缺省操作:立即返回

Unix网络编程学习笔记——close与shutdown_第1张图片


在使用close函数终止网络连接时存在以下两个限制。

1. close将描述字的访问计数减1,仅在此计数为0时才去关闭套接字。而在有些场景下我们需要立即触发TCP连接终止的流程(FIN)而不管访问计数。

在多进程并发服务器中父进程关闭已连接套接字时,由于子进程仍在使用该套接字,所以它的访问技术不为0,这次close调用不不会触发TCP的终止连接的四次握手。

在多进程并发服务器中要求父进程必须对没个accpet以后返回的已连接套接字调用close,否则父进程将可能会耗尽所有的套接字描述符,因为任何一个进程在某个时刻打开的描述符字数总是有限的。更重要的是,如果父进程不close那么最终没有一个客户连接会被终止,因为所有已连接套接字的访问计数都不为0(至少都被父进程使用)。

2. close同时终止了数据传送的两个方向:读与写。而在有些场景下我们需要一种机制分别终止数据传送的读与写。

由于TCP连接时全双工的,很多时候我们需要通知另一端我们已完成了数据发送,即使另一端还有许多数据要发送。


用linux提供的shutdown函数可以很好的解决上述两个限制条件。


int shutdown(int sockfd, int howto);


先看一个典型的shutdown的使用场景,如下图:

Unix网络编程学习笔记——close与shutdown_第2张图片


shutdown函数的行为依赖于参数howto的值

SHUT_RD    关闭连接的读这一半,不再接受套接字中的数据并且现有的套接字接受缓冲区中的数据都将作废,进程不能再对套接字做任何读操作。套接字本身接受的任何数据都被确认,但数据本身都被丢弃。

SHUT_WR    关闭连接的写这一半,在TCP中这被称为半关闭。当前留在套接口发送缓冲区中的数据都被发送,随后紧接着TCP连接终止流程。不论改套接字的访问计数是否大于0,进程不能再执行任何写操作。

SHUT_RDWR    连接的读和写都关闭。等效于调用shutdown两次,一次用SHUT_RD,一次用SHUT_WR。



你可能感兴趣的:(网络编程)