免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: seufy88
打印 上一主题 下一主题

[Linux] socket中close和shutdown的区别 [复制链接]

论坛徽章:
1
双子座
日期:2013-11-06 17:18:01
11 [报告]
发表于 2014-04-02 16:07 |只看该作者
gaojl0728 发表于 2014-04-02 14:08
回复 7# timespace

应该是:

“close后,l_onoff非0且l_linger=0, 只有在此时TCP的读队列数据的情况下, 才会暴力发送RST, 否则内核还是会四次握手的。”

论坛徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
12 [报告]
发表于 2014-04-02 16:12 |只看该作者
回复 10# timespace


不好意思是我回复有点问题, 说的不太全面:
调用close后, 内核会先检查TCP读取队列,
1. 如果有数据没有读完, 不管linger选项是任何值, 内核总是会发送RST给对端,
2. 如果没有数据可读,内核接着检查linger选项, 如果l_onoff非0且l_linger=0, 也会发送RST
3. 其他情况会发送FIN进行四次挥手。同时如果l_onoff非0且l_linger>0,  close调用会阻塞在这里等待l_linger的时间。

所以你说的情况也会发送RST的。

论坛徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
13 [报告]
发表于 2014-04-02 16:19 |只看该作者
回复 11# seufy88


        那我回复写的有问题,他说的是对的。close完整的流程看我楼上的回复。

论坛徽章:
1
双子座
日期:2013-11-06 17:18:01
14 [报告]
发表于 2014-04-02 16:25 |只看该作者
回复 9# gaojl0728


    请问,如果socket的引用数>2, 此时close(socket),在减少引用数的基础上,应该不会发送FIN吧,因为其他共享这个socket 的进程需要使用


(2)如果此后收到的是带ACK的纯数据包,会有所不同,
        a. 如果前面是close调用, local端进入FIN_WAIT2, 同时启动time wait定期器,最终会关闭local端的TCP链接.
==》进入FIN_WAIT2后,就不接收对方发来的data 了吗?
我的理解是,local侧还是可以继续接收数据并返回ack, 只是这些数据丢弃掉了。application对这个socket当然肯定也不能再read

论坛徽章:
1
双子座
日期:2013-11-06 17:18:01
15 [报告]
发表于 2014-04-02 16:41 |只看该作者
@timespace
@gaojl0728
感谢两位的解答。

论坛徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
16 [报告]
发表于 2014-04-02 16:56 |只看该作者
回复 14# seufy88


我前面说“同时启动time wait定期器,最终会关闭local端的TCP链接”是基于一般情况下local调用close发送了FIN给对端之后, 对端这时应该会发送FIN+ACK包回来的情况,但如果对端来的还不是FIN+ACK包,而是数据包,
1. 如果数据包带ACK,  这些数据包还是会进入TCP收队列,
2. 如果数据包不带ACK, 直接丢掉。

不过Linux这块代码好像有点问题, 如果对端发来的是纯FIN包, 而不是FIN+ACK包,内核也会丢掉。
也就是说对端回过来FIN+ACK, 没问题。但是先回FIN, 再回ACK就不行了, 很奇怪。不太符合协议。

论坛徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
17 [报告]
发表于 2014-04-02 17:09 |只看该作者
回复 16# gaojl0728


完整的过程是本端调用close发送FIN给对方, 此时本端进入FIN_WAIT_1,
如果此时对端发过来不带ACK的包(包括纯FIN包和纯数据包),直接丢掉, 如果是带ACK的数据包, 本端会进入FIN_WAIT_2, 同时这个数据包也会进入TCP队列, 此后如果来的还是带ACK的数据包, 数据包还能进入TCP队列。
直到FIN+ACK为止, 其他包都丢掉了。

论坛徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
18 [报告]
发表于 2014-04-02 17:09 |只看该作者
回复 16# gaojl0728


完整的过程是本端调用close发送FIN给对方, 此时本端进入FIN_WAIT_1,
如果此时对端发过来不带ACK的包(包括纯FIN包和纯数据包),直接丢掉, 如果是带ACK的数据包, 本端会进入FIN_WAIT_2, 同时这个数据包也会进入TCP队列, 此后如果来的还是带ACK的数据包, 数据包还能进入TCP队列。
直到FIN+ACK为止, 其他包都丢掉了。

论坛徽章:
1
双子座
日期:2013-11-06 17:18:01
19 [报告]
发表于 2014-04-02 17:16 |只看该作者
回复 12# gaojl0728


    如此说来,对于以close方式主动关闭的一侧,是有很大程度会造成RST,而不是正常的四次BYBY
  timing很重要。直接close的时候,并不能保证buffer队列里没有要读的数据。

论坛徽章:
1
双子座
日期:2013-11-06 17:18:01
20 [报告]
发表于 2014-04-02 17:20 |只看该作者
gaojl0728 发表于 2014-04-02 17:09
回复 16# gaojl0728


完整的过程是本端调用close发送FIN给对方, 此时本端进入FIN_WAIT_1,

=》 本端发送完FIN后,如果之前本端发送的数据segment有丢失,对方会一直请求这个丢失的segment的序列号,些时,本端还是可以重发的吧?
直到对方对这个segment进行ACK(也可能对方重新收到丢失的segment后,直接发送FIN的ACK)

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP