TCP 连接中服务端长时间处于 FIN_WAIT1 状态, 客户端是否无法收到 Close 事件? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Mohanson
V2EX    问与答

TCP 连接中服务端长时间处于 FIN_WAIT1 状态, 客户端是否无法收到 Close 事件?

  •  
  •   Mohanson 2019-12-10 20:14:03 +08:00 4157 次点击
    这是一个创建于 2200 天前的主题,其中的信息可能已经有所发展或是发生改变。

    服务端正发送数据给客户端, 服务端在数据发送完毕后 Close 链接, netstat 发现这个链接进入了 FIN_WAIT1 状态, 客户端的 Read 调用也没有被终止(正常情况下, 服务端 Close 后, 客户端的 Read 会报 use of closed network connection 错误, 但服务端进入 FIN_WAIT1 的时候客户端好像不知道这个链接已经被关闭了还在傻傻等待数据).

    12 条回复    2019-12-11 09:07:35 +08:00
    wish198
        1
    wish198  
       2019-12-10 20:30:49 +08:00
    按你这个说法,你客户端得自己判断出来主动关闭呀,TCP 四次挥手看下
    Mohanson
        2
    Mohanson  
    OP
       2019-12-10 20:46:21 +08:00
    @wish198 我看过 TCP 挥手过程, FIN_WAIT1 是等待对方 ACK. 我目前发现存在题目描述的现象, 但是无法在互联网上找到确切的文字资料来证明这种现象, 因此来问一下看看是否有大佬能提供下文字资料 /Spec 等等的东西证明我的猜测是正确的还是错误的...
    lhx2008
        3
    lhx2008  
       2019-12-10 20:59:48 +08:00
    如果客户端没收到 ,就不会确认相关的信息,服务端那边就超时,会重发 Close
    alcarl
        4/span>
    alcarl  
       2019-12-10 21:01:43 +08:00 via Android
    有可能对面的防火墙把你发过去的 fin 包过滤了,对面应用没有收到你的 fin,网络上没有其他东西的话,finwait1 阶段是内核控制的对面也是内核控制,应该会自己过度到 finwait2,对面过度到 closewait,然后才是对面应用处理。没进 closewait 客户端当然读不到 eof
    alcarl
        5
    alcarl  
       2019-12-10 21:03:33 +08:00 via Android
    @Mohanson 搜索 tcp 四次挥手?
    unixeno
        6
    unixeno  
       2019-12-10 21:16:04 +08:00   2
    查了一下这个问题,你可以看看这个 https://blog.huoding.com/2014/11/06/383,还有这个 https://blog.csdn.net/dog250/article/details/81697403

    在你服务端 close 之后,连接会立即进入 FIN_WAIT1 状态,如果客户端的接收缓冲区里还有数据,FIN 是不会影响客户端读取的。
    而且如果客户端一直不接收数据,以至于客户端接收队列满了,服务端的 FIN 是发不出去的,这个链接会一直处于 FIN_WAIT1 状态,只有重启系统或者等待零窗口探测包超过 tcp_orphan_retries 参数限制时触发销毁连接
    Mohanson
        7
    Mohanson  
    OP
       2019-12-10 21:48:38 +08:00 via Android
    @unixeno 谢谢,有个问题哈,如果 fin 包被拦截,那 tcp 对端是否永远也不知道这个链接被关闭了呢?
    bitcross
        8
    bitcross  
       2019-12-10 22:03:20 +08:00
    @Mohanson 对,所以才有的 keepalive 的设计,及时检测出已经”不可达”的 session

    建议你用 wireshark 之类的抓包工具在客户端抓一下包,看看 fin 包到底有没送过来
    没有的话十有八九就是路由器,防火墙之类的给拦截了,这就要在这些网络设备里检查数据包日志了
    Mohanson
        9
    Mohanson  
    OP
       2019-12-10 22:05:25 +08:00
    @bitcross 好的, 谢谢!
    unixeno
        10
    unixeno  
       2019-12-10 22:10:34 +08:00 via Android
    @Mohanson 也可以,需要你向对方发送数据,连接不存在的时候会直接 reset

    不通信的情况下,那肯定是没办法知道对方是不是还在线的
    Buges
        11
    Buges  
       2019-12-10 22:17:28 +08:00 via Android
    关键词:close()与 shutdown()的区别,自己去搜吧。
    wish198
        12
    wish198  
       2019-12-11 09:07:35 +08:00
    @Mohanson TCP 是有半关闭的,你找个 Wireshark 抓一下包就明白了,不是服务器发来 Fin,你的客户端就要自己关闭
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     919 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 20:27 PVG 04:27 LAX 12:27 JFK 15:27
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86