• 那时刻
    2022-01-19
    请问老师,客户端用 RST 来断开连接并不妥当,需要从代码上找原因。比如客户端在 Receive Buffer 里还有数据未被读取的情况下,就调用了 close()。调用close,是不是应该发fin包呢?什么时候会发rst包?

    作者回复: 这是内核的行为。close()系统调用会走到tcp_close(),在这个函数里,会做判断,如果buffer里还有数据未读,它就直接调用tcp_send_active_reset(),发出RST,并把这个连接直接设置到CLOSED状态,也就是不进入TIME_WAIT。 对于这种情况,为了避免close()时候发出RST,就需要检查业务代码,确保在调用close()之前,把接收缓冲里的数据读取掉。

    共 5 条评论
    12
  • *
    2022-01-27
    老师,tcp.ack和tcp.flags.ack有什么不同,为什么问题1的答案是tcp.ack==1 and tcp.flags.reset == 1

    作者回复: 答案是tcp.flags.ack == 1 and tcp.flags.reset == 1 tcp.ack是指报文的确认号,是一个数字 tcp.flags.ack和tcp.flags.reset都是报文的TCP标志位,不是0就是1

    共 4 条评论
    9
  • kaixiao7
    2022-05-03
    老师,在客户端握手的第三个RST+ACK报文中,为什么会出现RST呢?有哪些情况会出现呢?

    作者回复: 你好,这个要看具体的场景逻辑,有一种场景就是握手的第三个报文是RST+ACK的,那就是健康检查,也就是对服务端口的可达性的检查。发起端发送SYN,服务端回复SYN+ACK,发起端此时知道这个服务端口是可用的(健康的),此时探测任务已经完成了。而用RST+ACK的话可以明确的让服务端关闭这个连接请求(释放资源),在发起端(客户端)也是可以回收资源,对双方都有利。

    
    8
  • 一步
    2022-01-25
    最后一个图 有个疑问的, 为什么客户端在初始化关闭的时候 除了发送一个 FIN ,还有个 ACK呢,是为了回复上一个服务端发送的数据吗?

    作者回复: 是的,就是确认它收到的上一个报文。在TCP里面,基本上除了握手的第一个报文SYN,其他报文都带ACK标志位

    共 3 条评论
    5
  • 乌龟爱上金鱼
    2022-09-19 来自上海
    老师您好,对端向我发了fin,我这边ack后没有close,进入closewait,对端现在应该是finwait2,按理来说对端现在只是不向我发送数据了,但是能接受数据,但是我继续向对端发送数据后,对端回复的是reset,这是为什么呀?

    作者回复: 您好,这确实是一个有意思的话题。TCP确实可以做“半关闭”行为,但是仅根据对端发出的一个FIN报文是无法确切的判定对端是全关闭(同时关闭读和写)还是半关闭(只关闭写)的。但是对端在FIN报文后的行为倒是可以帮助我们做进一步的判断。 比如你遇到的情况是,收到FIN后,你继续发送数据,对端回复了RST。这大概率说明对端是同时关闭了读和写了。也就是说,对端发出FIN的同时,它这个socket已经既不能写入数据(也就是发给你数据),也不能接受数据(也就是接收你在收到FIN后发送的更多的数据报文)了。由于此时对端这个socket处于这种不可读写的状态,所以当对端的内核收到了你的数据报文时,它就用RST做了回复。 当然,如果对端的FIN是由shutdown(sockfd, SHUT_WR)触发的,那就只是关闭写的方向,也会同样发送FIN给你,而此时你继续发送数据报文,对端还是有可能会接收的。总之还是看具体的代码场景了~ 所以我推测,对端当时是用shutdown(sockfd, SHUT_RDWR)或者close(sockfd)来关闭这个连接的。供你参考。

    
    3
  • 上杉夏香
    2022-06-27
    这篇文章的最后一张图,是不是有些瑕疵?进入半连接状态后,服务端继续发送数据,当服务器发送FIN报文的时候,它的seq应该不再是L?

    作者回复: 这个图是Stevens的书中的原图。之前没留意,你这么说,我觉得真是个问题。服务器发送的FIN的seq应该是L加上最后一次data的length。你好仔细!~

    
    3
  • lxj
    2022-04-04
    有一点点小提议,分析一个问题能把如何抓包,在哪端抓包,抓包时间点,过滤条件再交代详细点嘛,感觉分析的粒度太粗了,上下文没有交代清楚

    作者回复: 你好,这次的抓包细节是这样的: “所以,我们就展开了抓包工作。具体做法是:我们需要选择一端做抓包,这次是客户端;检查应用日志,发现没几分钟就出现了 connection reset by peer 的报错;对照报错日志和抓包文件,寻找线索。” 对应你的几个问题: 如何抓包:用tcpdump 在哪端抓包:客户端 抓包时间点:这个没有特别的讲究,因为问题一直在发生,随时可以抓 过滤条件: tcpdump host 服务端IP 抓了几分钟就发现日志里有我们找的报错,此时就可以把抓包停止了。因为很容易复现,所以抓包时间不长,只有3分25秒。具体的抓包示例文件我很快上传:)

    
    3
  • sysho
    2022-04-20
    这两个月刚好排查了几个抓包问题,觉得老师这节课讲得真好,看得很爽。

    作者回复: 是的,抓包分析入门后会发现越来越多的乐趣:)

    
    2
  • 简迷离
    2022-03-27
    老师,案例中的抓包文件能提供下吗?这样单独的看文章分析效果还是有限,能提供下案例抓包文件边看边分析数据包效果更佳,还请老师提供下,谢谢您!

    作者回复: 您好,后面从第6讲开始大部分都有抓包示例文件了,供你参考~ 这一讲的文件我整理一下:)

    
    1
  • 仲晶晶
    2022-01-27
    老师您好,我这边做openresty测试的时候遇到个现象: jemter通过F5压测到openresty网关的时候(TPS 5k-6k)左右,这个时候用的都是短链接,我就看到很多TW,这说明断链都是在网关这边断链的,我比较疑惑什么情况下服务端(网关)会发生断链呢(发FIN)?

    作者回复: openrestry我了解不多,不过从协议来看,你在openrestry网关上看到很多TW,那就意味着网关主动发起了关闭,你的这个判断是正确的。 你的测试场景是不是这样:Jmeter -> F5 -> openrestry 你这里提到“用的都是短连接”,应该是指JMeter或者F5做了这个配置对吧,那么按照http协议规范,如果客户端(这里是Jmeter或者F5)发送的http请求里面携带Connection: close头部,web server(这里是openrestry)有可能会主动发起关闭。我这里说“有可能”是因为我也注意到有些web server并不会那么做,也许是考虑到了主动关闭会引发自己进入TW状态,而这种状态的连接越多,对web server自己越不利。

    
    1