套接字API(六)close函数和shutdown函数

一 close与shutdown的区别:

*close函数:将描述符的访问计数减1,仅在计数为0时才关闭套接字(从而激发TCP的正常连接终止序列,即发送FIN)。

*shutdown函数:不管引用计数的值是否为0,都可以激发TCP的正常连接终止次序。

*close函数同时终止两个方向的数据传送:读和写。

*shutdown可以只终止一个方向的数据传送。

*close的套接字描述符不能再被应用进程使用,即它不能再作为read或write的参数;shutdown关闭读仍然可以write,关闭写仍然可以read。


二 close函数:将描述符的访问计数减1,仅在计数为0时才关闭套接字(从而激发TCP的正常连接终止序列,即发送FIN)。

(1)TCP socket的close的缺省功能:将套接字做上“已关闭”标记,并立即返回进程。

*这个套接字描述符不能再为进程所用:它不能作为函数read或write的参数。

*但TCP试着发送已排队待发的任何数据,然后按照正常的TCP连接终止次序进行操作(即发送FIN)。

*套接字选项SO_LINGER可用来改变TCP套接字的close函数的缺省功能。

(2)并发服务器中父进程关闭已连接套接字,只是将套接字描述符的引用计数值减1(父子进程间共享文件表项),由于引用计数值任然大于0,所以这次close操作并不引发TCP的四分组连接终止序列。

(3)如果父进程不对每个由accept返回的已连接套接字描述符调用close的后果:

*首先,父进程最终会耗尽可用描述符,因为任何进程在某时刻打开的描述符是有限的。

*更重要:没有一个客户连接被终止。当子进程关闭已连接套接字时,它的引用计数由2减为1且保持为1,这将妨碍TCP连接终止序列的执行,从而连接永远保持开放。

(4)TCP发送FIN的情况:

*应用进程调用close函数(引用计数需为0);

*应用进程自愿终止时(调用exit或从main函数返回);

*应用进程不自愿终止(收到一个终止进程的信号)。


三 shutdown函数:不管引用计数的值是否为0,都可以激发TCP的正常连接终止次序。

*格式:int shutdown(int sockfd,int howto)

(1)参数howto:

*SHUT_RD:关闭连接的读这一半,不再接收套接字中的数据且保留在套接字接受缓冲区的数据将被丢弃。进程不能再对套接字进行任何读操作。使用SHUT_RD调用shutdown后,由TCP套据字接收的任何数据都被确认,但数据本身丢掉。

*SHUT_WR:关闭连接的写一半,当前套接字发送缓冲区中的数据都将被发送,后跟正常的TCP连接终止序列,进程不能再对该套接字执行任何写函数。

*SHUT_RDWR:连接的读一半和写一半都关闭。


四 SO_LINGER套接字选项对close函数的影响:(linger:徘徊、逗留)

(一)默认情况下:close立即返回,但是如果有数据在发送缓冲区中,系统将试着把这些数据发送给对端

(二)SO_LINGER选项:

1.本选项要求在用户进程和内核间传递如下结构,定义在<sys/socket.h>

struct linger

{

int l_onoff;/*0=off,非零=n*/

int l_linger;/*linger time:posix指定秒为单位*/

}

2.setsockopt将两个结构成员的值形成如下三种情形:

*l_onoff为0:那么关闭本选项,l_linger的值被忽略,先前的默认情况生效,close立即返回。如下图:


*l_onoff为非0且l_linger为0:当close终止某个连接时,TCP将丢弃保留在套接字发送缓冲区中的任何数据,并发一个RST给对端(强制终止TCP连接),而没有通常的四分组连接终止序列,从而避免了TIME_WAIT状态,但通常不提倡。

*l_onff为非0且l_linger为非0:当套接字关闭时内核将拖延一段时间。即如果在套接字发送缓冲区中还有数据,那么进程将被投入睡眠,直到:所有数据都已发送并且均被对方确认;或延迟时间到。如果在数据发送完并被确认前延滞时间到,close将返回EWOULDBLOCK错误,并且套接字缓冲区中的任何数据都被丢弃。如下两图:


3.当使用SO_LINGER选项时,应用进程检查close的返回值是非常重要的:

*如果在数据发送完并被确认前延滞时间到,close将返回EWOULDBLOCK错误,并且套接字缓冲区中的任何数据都被丢弃。


(三)让客户知道服务器已去读数据:

1.设置SO_LINGER选项+close成功发回:告诉我们先前发送的数据已被对端TCP确认。

2.让客户知道服务器进程已读取数据的方法:

*调用shutdown(设置SHUT_WR)取代close,并等待对端close连接。如下图:


*使用应用ACK。如下图




















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值