网络排查案例课
杨胜辉
eBay 资深运维专家,流量系统负责人
22781 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 39 讲
实战三:不用抓包就能做的网络排查篇 (2讲)
网络排查案例课
15
15
1.0x
00:00/00:00
登录|注册

03 | 握手:TCP连接都是用TCP协议沟通的吗?

可能但罕见,双方都发送SYN
连接由四元组定义,不仅限于端口数量
UDP无连接,nc命令可能误导
缺少握手包可能导致误解
确定正确的接收窗口大小
只在握手阶段协商
解决大带宽下的窗口限制
netstat
Wireshark
tcpdump
ICMP Destination unreachable
TCP RST
net.ipv4.tcp_synack_retries
net.ipv4.tcp_syn_retries
指数退避原则
客户端重试发送SYN
客户端无法区分丢包原因
服务端不回应SYN
Piggybacking(数据捎带)
SYN和ACK的作用
确立双方准备好通信的意愿和能力
客户端发送ACK
服务端回复SYN+ACK
客户端发送SYN
实践和理论结合可以提升对TCP握手的理解
掌握握手知识对排查网络问题至关重要
TCP握手是连接的基础
Window Scale 启用条件?
net.ipv4.tcp_synack_retries 参数作用?
同时发起握手
TCP连接限制
UDP握手
握手包重要性
Window Scale
排查工具
拒绝方式
内核参数
重试策略
静默丢包
握手中的技术点
握手目的
三次握手过程
小结
思考题
常见误区
TCP握手扩展知识
TCP握手拒绝
TCP握手问题排查
TCP握手基础
TCP握手知识总结

该思维导图由 AI 生成,仅供参考

你好,我是胜辉。
在前面预习篇的两节课里,我们一起回顾和学习了网络分层模型与排查工具,也初步学习了一下抓包分析技术。相信现在的你,已经比刚开始的时候多了不少底气了。那么从今天开始,我们就要正式进入 TCP 这本大部头,而首先要攻破的,就是握手和挥手。
TCP 的三次握手非常有名,我们工作中也时常能用到,所以这块知识的实用性是很强的。更不用说,技术面试里面,无论是什么岗位,似乎只要是技术岗,都可能会问到 TCP 握手。可见,它跟操作系统基础、编程基础等类似,同属于计算机技术的底座之一。
握手,说简单也简单,不就是三次握手嘛。说复杂也复杂,别看只是三次握手,中间还是有不少学问的,有些看似复杂的问题,也能用握手的技术来解决。不信你就跟我看这几个案例。

TCP 连接都是用 TCP 协议沟通的吗?

看到这个小标题,可能你都觉得奇怪了:TCP 连接不用 TCP 协议沟通还用什么呢?
确实,一般来说 TCP 连接是标准的 TCP 三次握手完成的:
客户端发送 SYN;
服务端收到 SYN 后,回复 SYN+ACK;
客户端收到 SYN+ACK 后,回复 ACK。
这里面 SYN 会在两端各发送一次,表示“我准备好了,可以开始连接了”。ACK 也是两端各发送了一次,表示“我知道你准备好了,我们开始通信吧”。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了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-18
    5
    26
  • 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-09
    16
  • Geek_cad238
    其实Window Scale是常识,并不是冷门,😂,关于这个,在林沛满大佬的《wireshark网络分析就这么简单》一书里有详细说明,大家可以一看。

    作者回复: 👍林老师是这方面的先行者,非常厉害!

    2022-01-20
    3
    11
  • 首富手记
    一个客户端(假设只有一个出口 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-18
    8
  • 魏玉会 Gabby
    老师讲的真好,我一个前端人员也能看的懂

    作者回复: 对我也是很好的鼓励,大家一起加油:)

    2022-01-20
    6
  • steven
    在握手期间window是不会被scale放大的,但是我发现在传输过程中的window有260000+,但是握手的时候我客户端最大只有65535,服务端只有8000+,和我理解的有点不太一样呀

    作者回复: 对呀,握手期间,也就是发送SYN, SYN+ACK, ACK这段时间里,窗口是不放大的,也就是最大也只有65535。握手完成后也就是传输开始后,就可以应用这个放大系数了,跟你描述的现象很符合啊:)

    2022-03-12
    5
  • beanSeedling
    1. 第二次握手最大重传次数 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-18
    5
  • CentOS Linux release 7.6 , net.ipv4.tcp_syn_retries = 6 设置静默丢包,客户端重试的时候,发现尝试了 11次,前5次是每隔1s 后面几次就根据指数退避原则了,我这个环境为什么会多了 4次呢?

    作者回复: 这个问题有意思,我找个时间搭个环境测试一下。不过我推测,有可能其中几次是TCP retransmission,是syn_retries控制次数以外的~

    2022-01-20
    2
    2
  • 江山如画
    问题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-17
    2
    2
  • 明翼
    发送窗口大小扩展信息只能握手包发,那后面的发送窗口的变化只能改发送窗口的值而不是倍数对吗?

    作者回复: 对,倍数是握手阶段就确定了的,后续过程中不可以改变倍数,但可以改变基数

    2023-09-22归属地:四川
    1
收起评论
显示
设置
留言
46
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部