前言
这段时间面试官都挺忙的,频频出现在博客文章标题,虽然我不是特别想蹭热度,但是实在想不到好的标题了-。-,蹭蹭就蹭蹭 😃
事实上我在阿里面试的时候确实被问到了这个问题,HTTP、HTTPS、TCP/IP、Socket通信、三次握手四次挥手过程?当时虽然思路正确,可惜最终也并不算完全答对
结束后花了一段时间整理了下思路,参考和查阅了一下资料,整理如下:
来源:编程充电宝
作者:在所不辞
问题描述
你能否讲解一下TCP
的三次握手与四次挥手呢?
面试官如果从整体到局部入手,那我们就先讲讲整个三次握手和四次挥手的过程,但不要忘记,讲的同时应该适当体现你对该知识点掌握的深度和广度,具体怎么说,我们后面慢慢道来。
三次握手
所谓的握手
即一次发包到接收的过程,可能从客户端发送到服务端,也可能从服务端发送到客户端。
过程描述
先上一张TCP报文结构
图,待会我们会回来看这张图:
TCP报文结构
先上三次握手的流程图:
三次握手
接下来我们来详细讲解下上图的过程:
-
客户主机发起连接请求,设置
SYN
标志位为1
,同时客户端随机
选择了一个初始序号client_isn
,并且存放在TCP报文
字段的序号
中,如下图:第一次握手:SYN报文
-
接下来,当服务端接收到该报文后,会为其分配
TCP 缓存和变量
(这使得TCP容易受到被称为SYN 洪泛攻击
的拒绝服务攻击)紧接着,服务端会返回一个SYNACK 报文
到客户端,其中SYN
标志位为1
,确认号
设置为client_isn + 1
,并且选一个自己的初始序号server_isn
,并放置在序号
字段中,如下图:第二次握手:SYNACK报文
-
当收到服务器发来的
SYNACK
报文段后,客户端也需要给该连接分配缓存和变量,然后再次发送一个确认报文给服务端,其中,SYN
标志位设置为0
,将确认号
设置为server_isn + 1
,另外,此次报文可以携带负载数据:第三次握手:ACK报文
细节拓展
-
三次握手的状态转换图(建议达到能默写下来的熟练程度)
三次握手状态图
-
服务器为什么要使用特殊的初始序号
server_isn
?这为什么是必要的呢?
这个细节和问题深究第3题
是一致的,服务器使用特定的初始序列号 server_isn
(从源
和目的地IP
和端口
的散列
中获取)可以用来抵御SYN洪水攻击。具体为什么,以及什么是SYN 洪泛攻击
,问题深究部分我们会再详谈。