前言
TCP的三次握手和四次挥手常作为面试题考察程序员对于TCP握手协议的理解。该篇文章写于2018年, 此处为博客迁移,无内容增删。
TCP三次握手
假设 A 为客户端,B 为服务器端。
- 首先 B 处于 LISTEN(监听)状态,等待客户的连接请求。
- A 向 B 发送连接请求报文段,SYN=1,ACK=0,选择一个初始的序号 x。
- B 收到连接请求报文段,如果同意建立连接,则向 A 发送连接确认报文段,SYN=1,ACK=1,确认号为 x+1,同时也选择一个初始的序号 y。
- A 收到 B 的连接确认报文段后,还要向 B 发出确认,确认号为 y+1,序号为 x+1。
- B 收到 A 的确认后,连接建立。
说明:
- SYN(synchronous)是TCP/IP建立连接时使用的握手信号.
- ACK (Acknowledgement)即是确认字符.TCP报文格式中的控制位由6个标志比特构成,其中一个就是ACK,ACK为1表示确认号有效,为0表示报文中不包含确认信息,忽略确认号字段。
- seq 是序列号,是为了连接以后传送数据用的,初始随机.
- ack 是期望对方继续发送的那个数据包的序列号.因为已经收到了序列号为x的数据包,准备接收序列号为x+1的包,所以ack=x+1
举个例子
- 第一次(A—>B),SYN=1,seq=x
- 第二次(B—>A),SYN=1,ACK=1,seq=y,ack=x+1 //seq为什么是y,ack为什么是x+1?
- 第三次(A—>B),ACK=1,seq=x+1,ack=y+1 //seq为什么是x+1,ack为什么是y+1?
1 | seq是序列号,这是为了连接以后传送数据用的,ack是对收到的数据包的确认,值是等待接收的数据包的序列号。 |
TCP四次挥手
以下描述不讨论序号和确认号,因为序号和确认号的规则比较简单。并且不讨论 ACK,因为 ACK 在连接建立之后都为 1。
- A 发送连接释放报文段,FIN=1;
- B 收到之后发出确认,此时 TCP 属于半关闭状态,B 能向 A 发送数据但是 A 不能向 B 发送数据;
- 当 B 要不再需要连接时,发送连接释放请求报文段,FIN=1;
- A 收到后发出确认,此时连接释放。