TCP/IP协议栈
应用层
DNS协议
传输层
TCP协议
TCP协议报文结构
- 源端口
- 目的端口
- 序列号
- 确认号
- 头长度
header length or data offset
- 保留字段
reserved
- 状态字段
- URG
- ACK
- PSH
- RST
- SYN
- FIN
- 窗口字段
- 校验和
- 紧急指针
- 可选字段
- 数据
TCP协议三次握手
TCP三次握手是一个老生常谈的问题。为了方便理解,我们首先来模拟A基地和B基地通信的问题,核心的问题是A基地和B基地如何确认双方的发送和接收能力。
首先,我们要去掉上帝视角、沉浸进去扮演一个角色。我们是A基地,现在我们想和B基地建立通信,首先我们给B基地发一个“hello”,等待B基地的回复。这时候B基地在收到我们的信息之后,回发一个“我收到了你的信息”。我们A基地收到B基地的回复“我收到了你的信息”之后,我们就能知道B基地的接收和发送能力都没有问题。但是站在B基地的视角,B基地不知道我们是否收到这条回发消息,所以此时B基地出于安全考虑就不会发消息,因为他们无法确定我们A基地是否有接收能力,B基地只能够知道A基地有发送能力。所以需要我们再发一次“我们收到了你的回复”信息给B基地。B基地在收到我们的回发消息就能够确认我们A基地收到了回复,这样B基地就能够知道我们的接收能力也没有问题。此时才能够安全通信。所以我们总结一下,其实TCP三次握手就是为了确定两者都具有发送和接收的能力。所以发包总共三次,确认总共两次。
值得一提的是,TCP连接发起是由客户端发起的,并不能由服务端发起。
所以我们来分析一下上图的三次握手,
- 客户端发送
SYN
包,生成随机序列号seq = x
; - 服务端发送
SYN, ACK
包,生成随机序列号seq = y
,对上一次的确认ack = x + 1
; - 客户端发送
ACK
包,生成上一次确认号ack = y + 1
。