关闭套接字close还是shutdown

close

这个函数会对套接字引用计数-1,一旦发现引用计数到0,就会对套接字进行彻底释放,并且会关闭tcp两个方向的数据流。

因为套接字可以被多个进程共享,你可以理解为我们给每个套接字都设置了一个积分,如果我们通过fork的方式创建了子进程,套接字积分+1,如果我们调用一次close,套接字积分-1

close函数具体是如何关闭两个方向的数据流呢?

在输入方向,系统内核会将该套接字设置为不可读,任何操作都会返回异常。

在输出方向,系统内核尝试将发送缓冲区的数据发送给对端,并最后向对端发送一个FIN报文,接下来如果再对该套接字进行写操作,则会返回异常。

如果对端没有检测到套接字已经关闭,还继续发送报文,就会收到一个RST报文,告诉对端:“Hi,我已经关闭了,别再给我发送数据了”。

shutdown

shutdown可以关闭一个连接的方向

int shutdown(int sockfd, int howto)

howto是这个函数的设置选项,它的设置主要有三个选项

SHUT_RD(0):关闭连接的读方向,对该套接字进行读操作直接返回EOF。从数据角度来看,套接字上接收缓冲区已有的数据将被丢弃,如果再有数据到达,会对数据进行ACK,然后悄悄丢弃。也就是说,对端还会收到ACK,在这种情况下不知道发送的数据已经被丢弃了。

SHUT_WR(1):关闭连接的写方向,这就是常被称为半关闭的连接。此时,不管套接字引用计数的值是多少,都会直接关闭连接的写方向。套接字上发送缓冲区已有的数据将被立即发送出去,并发送给对端一个FIN报文。应用程序再对该套接字进行写操作将会报错。还是会接收对端的数据的。

SHUT_RW(2):关闭套接字的读和写两个方向。这个看起来和直接调用close没区别,但是还是有差别的。

1.close会关闭连接,并释放所有连接对应的资源,而shutdown并不会立刻主动释放掉套接字和所有的资源。

2.close存在引用计数的概念,并不一定会导致该套接字不可用, shutdown则不会管引用计数,直接使得该套接字不可用,如果别的进程还在使用该套接字,将会收到影响。

3.close的引用计数导致不一定会发出FIN报文(因为引用计数???),而shutdown则总是会发出FIN报文,这在我们打算关闭连接通知对端的时候,非常重要。

直接调用close和使用shutdown关闭写方向的过程如上图。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值