03 | 握手:TCP连接都是用TCP协议沟通的吗?
该思维导图由 AI 生成,仅供参考
TCP 连接都是用 TCP 协议沟通的吗?
- 深入了解
- 翻译
- 解释
- 总结
本文深入探讨了TCP连接的复杂性和挑战,以及解决相关问题的方法。作者首先指出了TCP连接并非总是使用TCP协议进行通信,服务端也可能拒绝握手请求,导致客户端无法确定握手请求的具体情况。了解TCP握手和挥手的技术对于网络工程师和技术面试都具有重要意义。文章通过实验和分析展示了TCP连接的复杂性,以及tcpdump和Wireshark在网络分析方面的重要性。此外,作者还提到了TCP握手拒绝可以通过ICMP消息来达成,这一点可能会让读者对网络知识产生新的认识。另外,文章还涉及了UDP的握手问题以及TCP连接数量的误解。通过深入分析和实际案例,读者可以更好地理解TCP连接的工作原理和排查故障的方法。整体而言,本文通过多个有趣的案例和深入分析,帮助读者更好地理解TCP连接的工作原理和排查故障的方法。
《网络排查案例课》,新⼈⾸单¥59
全部留言(46)
- 最新
- 精选
- 某人数退避原则本身就不建议在精确的整秒做重试,为什么?
作者回复: 假设这样一个场景: 1. 接收端有个定时任务,比如每隔1秒、2秒、4秒。。。这样反复运行,正好发送端的SYN包卡在第1秒,因为定时任务占用了全部CPU资源,导致SYN+ACK没有及时发出 2. 发送端接着正好也卡着2秒、4秒。。。这种时间点,每次都赶上对端那个定时任务,所以每次SYN都没有响应 3. 握手失败 这就是双方都精确翻倍的话,可能遇到的问题。同样的道理,对于一般的应用逻辑,其“重试”也最好是随机时间,或者是翻倍时间附近有一定的浮动,这样可以避免每次都“撞车”。不知道我这样说清楚没有:)
2022-01-18526 - MeowTvづ对于服务器端最多65535确实是个误区,其实这个跟很多都有关系的,比如服务器端的CPU、内存、fd数以及连接的情况,fd数是前提。一个连接会牵扯到服务端的接收缓冲区(net.ipv4.tcp_rmem)以及发送缓冲区(net.ipv4.tcp_wmem),一个空的TCP连接会消耗3.3KB左右的内存,如果发数据的话,一个连接占用的内存会更大。所以理论上4GB的机器理论上支持的空TCP连接可以达到100W个。此外数据经过内核协议栈的处理需要CPU,所以CPU的好坏也会影响连接数。
作者回复: 是的,所以C10K, C100K等经典问题就是讨论了这个主题~
2022-02-0916 - Geek_cad238其实Window Scale是常识,并不是冷门,😂,关于这个,在林沛满大佬的《wireshark网络分析就这么简单》一书里有详细说明,大家可以一看。
作者回复: 👍林老师是这方面的先行者,非常厉害!
2022-01-20311 - 首富手记一个客户端(假设只有一个出口 IP)和一个服务端(假设也只有一个 IP 和一个服务端口),那么确实只能最多发起 6 万多个连接。针对这句话,在centos 和ubuntu系统默认的情况下,tcp是没有办法建立起6万多个链接的,因为 net.ipv4.ip_local_port_range 这个参数固定了机器当做client 发起请求的时候使用的端口范围,所以默认的情况下,单向智能建立28231 个链接,这个是我们真实生产服务器上发生过的问题; 因为程序释放tcp有问题,所以机器上的timewite 过多,然后把这两万多个端口用完了,导致了服务之间链接异常;
作者回复: 嗯 6万多连接是纯理论的讨论,从TCP协议规范来说,最大确实有这么大。操作系统也在进化,在很早以前,1024以上的端口都可以用作动态源端口,但现在确实窄了很多了。 理论知识(比如TCP的端口最大范围),现实知识(比如当前linux普遍支持的local port range)并不矛盾,也最好都知道。
2022-01-188 - 魏玉会 Gabby老师讲的真好,我一个前端人员也能看的懂
作者回复: 对我也是很好的鼓励,大家一起加油:)
2022-01-206 - steven在握手期间window是不会被scale放大的,但是我发现在传输过程中的window有260000+,但是握手的时候我客户端最大只有65535,服务端只有8000+,和我理解的有点不太一样呀
作者回复: 对呀,握手期间,也就是发送SYN, SYN+ACK, ACK这段时间里,窗口是不放大的,也就是最大也只有65535。握手完成后也就是传输开始后,就可以应用这个放大系数了,跟你描述的现象很符合啊:)
2022-03-125 - beanSeedling1. 第二次握手最大重传次数 tcp_synack_retries (integer; default: 5; since Linux 2.2) The maximum number of times a SYN/ACK segment for a passive TCP connection will be retransmitted. This number should not be higher than 255. 2. This option is an offer, not a promise; both sides must send Window Scale options in their SYN segments to enable window scaling in either direction. This option may be sent in an initial <SYN> segment (i.e., a segment with the SYN bit on and the ACK bit off). It may also be sent in a <SYN,ACK> segment, but only if a Window Scale option was received in the initial <SYN> segment. 不会,从上诉RFC原文可以看出是必须双方都支持Window Scale,才会启用
作者回复: 很好,也看得出来做了功课:)
2022-01-185 - 奕CentOS Linux release 7.6 , net.ipv4.tcp_syn_retries = 6 设置静默丢包,客户端重试的时候,发现尝试了 11次,前5次是每隔1s 后面几次就根据指数退避原则了,我这个环境为什么会多了 4次呢?
作者回复: 这个问题有意思,我找个时间搭个环境测试一下。不过我推测,有可能其中几次是TCP retransmission,是syn_retries控制次数以外的~
2022-01-2022 - 江山如画问题1: 因为 net.ipv4.tcp_syn_retries 是三次握手的 SYN 包的重试次数,猜测 net.ipv4.tcp_synack_retries 是 SYN+ACK 包的重试次数,在 centos 上看了下,这个值默认是2. 问题2: 在RFC1332的2.2节 Window Scale Option中有一段 "Upon receiving a SYN segment with a Window Scale option containing shift.cnt = S, a TCP sets Snd.Wind.Scale to S and sets Rcv.Wind.Scale to R; otherwise, it sets both Snd.Wind.Scale and Rcv.Wind.Scale to zero." 所以当通信双方一方支持 windows scale, 另一方不支持时,再之后的通信中,发送窗口和接口窗口的缩放比例都是0,相当于双方的 Shift Count 的值都是0.
作者回复: 回答正确! 对于问题2,RFC1323的以下陈述可能更加明确一些:只有SYN里带这个option,那么接收端回复的SYN+ACK里才可以带上这个option;如果SYN里没有,SYN+ACK是不应该带这个option的(当然,因为客户度本身不支持,所以SYN+ACK带不带,效果都一样): This option may be sent in an initial <SYN> segment (i.e., a segment with the SYN bit on and the ACK bit off). It may also be sent in a <SYN,ACK> segment, but only if a Window Scale option was received in the initial <SYN> segment. A Window Scale option in a segment without a SYN bit should be ignored.
2022-01-1722 - 明翼发送窗口大小扩展信息只能握手包发,那后面的发送窗口的变化只能改发送窗口的值而不是倍数对吗?
作者回复: 对,倍数是握手阶段就确定了的,后续过程中不可以改变倍数,但可以改变基数
2023-09-22归属地:四川1