shutdown函数 & 套接字选项

本文深入探讨了TCP连接的管理机制,包括close与shutdown函数的区别、SO_KEEPALIVE选项的作用及linger结构的应用。此外还介绍了不同情况下TCP连接可能出现的问题及其处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有的时候客户端批量发送数据,发送完数据后,如果直接调用close(假设引用计数为0)

则发送端与接收端均被关闭。但可能管道中还有数据在传输,这时管道中对方的ack,以及fin的确认

就不能收到了,连接就不是正常关闭。

close函数把描述符的引用计数减一,仅仅在该计数变为0的时候,才真正的关闭套接字,而使用
shutdown函数可以不管引用计数就激发了TCP的正常连接终止序列;
close函数终止读和写两个方向的数据传输。既然TCP连接是全双工的,有时候我们需要告知对端我们已
经完成了数据发送,我们仅仅需要关闭数据发送的一个通道,但是我们还是可以接收到对端发送过来的
数据,这种控制只有利用shutdown函数才能实现。
1>.如果有多个进程共享一个套接字,close每被调用一次,计数减1,直到计数为0时,也就是所用进程
都调用了close,套接字将被释放。
2>. 在多进程中如果一个进程中shutdown(sfd,SHUT_RDWR)后其它的进程将无法进行通信. 如果一个
进程close(sfd)将不会影响到其它进程.


SO_DEBUG:本选项仅由TCP支持,当给一个TCP套接字开启此选项时,内核将为TCP在该套接字发送和

接受的所有分组保留详细跟踪信息

SO_ERROR:当一个套接字发生错误,源于BSD的内核中的协议模块将该套接字的名为so_error的变量设为标准的Unix

Exxx值中的一个,我们称它为该套接字的待处理错误。内核能够以以下两种方式通知进程这个错误:

1> 如果进程阻塞在对套接字的select调用上,那么无论检查可读条件还是可写条件,select均返回并设置

其中一或2个条件。

2> 如果进程使用信号驱动式I/O模型。那就给进程或进程组产生一个SIGIO信号。

SO_KEEPALIVE:设置该选项后,如果两小时内在该套接字的任一方向上都没数据

交换,TCP就自动给对端发送一个保持存活探测分节。这是一个对端必须响应的分节,

他会导致以下三种情况

1> 对端以期望的ACK响应。应用进程得不到通知(因为一切正常)。再又经过仍无动静的

2小时后,TCP将发出另一个探测分节

2> 对端以RST响应,它告知本段TCP,对端已经崩溃并重启。该套接字的待处理错误被置为

ECONNRESET,套接字本身则被关闭

3> 对端保持存活探测分节没有任何响应。源自BSD的TCP将另外发送8个探测分节。最后还得不

到响应的话就放弃。

SO_LINGER:

情形对端进程崩溃对端主机崩溃对端主机不可达
本端TCP正主动发送数据对端TCP发送一个FIN分节,
这通过使用select判断可读条件
立即能检测出来。如果本端TCP
发送另外一个分节。对端TCP就以
RST响应。如果在本端接受到RST
后禁用进程仍尝试写套接字。我们的
套接字实现就给进程发送一个SIGPIPE
信号
本端TCP将超时,且该套待
处理错误被置ETIMEDOUT
本端TCP将超时,且该套接字的待
处理错误被置为EHOSTUNREACH
本端TCP正主动接收数据对端TCP将发送一个FIN,我们将把它
作为一个(可能是过早的)EOF读入
我们将停止接受数据我们将停止接受数据
连接空闲,保持存活选项
(SO_KEEPALIVE)以设置
对端TCP发送一个FIN分节,
这通过使用select判断可读条件
立即能检测出来。
在毫无动静2小时后,
发送9个保持存活探测
分节。然后用套接字的
待处理错误被设置为
ETIMRDOUT
在毫无动静2小时后,
发送9个保持存活探测
分节。然后用套接字的
待处理错误被设置为
EHOSTUNREACH
连接空闲,保持存活选项
(SO_KEEPALIVE)以设置
对端TCP发送一个FIN分节,
这通过使用select判断可读条件
立即能检测出来。
struct  linger{

  int     l_onoff;

   int    l_linger;

};

函数说明
shutdown.SHUT_RD在套接字上不能再接受请求。进程仍可向套接字中发送数据。接受缓冲区数据被丢弃。再接收到的任何
数据都被丢弃。对套接字发送缓冲区没有影响
shutdown,SHUT_WR在套接字上不能再发送请求。进程仍可接收数据。发送缓冲区中的剩余数据将被发送 ,后跟FIN终止序列
close,l_onoff=0
(默认情况)
在套接字上不能再接受或发送数据。套接字发送缓冲区中的内容被发送到对端。接受缓冲区的内容被丢弃。
如果描述符的引用计数=0,那么发送完数据后,跟以FIN终止序列
close,l_onoff=1
l_linger=0
在套接字上不能再接受或发送数据。如果描述符的引用计数=0,RST被发送给对端。连接的状态置为
CLOSED(没有TIME_WAIT状态)。套接字发送缓冲区和套接字接受缓冲区都被丢弃
close,l_linger=1
l_linget !=0
在套接字上不能再接受或发送数据。发送缓冲区中的剩余数据将被发送 ,如果描述符的引用计数=0,在发送完发送缓冲区的数据后,跟以FIN终止序列。接受缓冲区的数据被丢弃。如果连接变为CLOSED状态前延滞
时间到,则返回E_WOULDBLOCK错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值