想象一下,TCP传输就像快递小哥送包裹,每个数据帧就像一个包裹的**快递单**,以下是几个关键的"快递单"信息:
- **源端口号 & 目的端口号**
-
**源端口号**:就像寄件人地址,告诉对方"这是谁发的"。
-
**目的端口号**:就像收件人地址,告诉数据"送到哪里"。
- **序列号(Sequence Number)**
- 数据分成一块块,就像书页的页码,**序列号**就是页码,保证数据到达后能按顺序拼好。
- **确认号(Acknowledgment Number)**
- 收件人收到包裹后,会用一个"签收单"告诉快递小哥"包裹几号到几号我都收到了,接下来请送后面的"。
- **标志位(Flags)**
-
**SYN**:打招呼------"你好,我想建立连接"。
-
**ACK**:点头------"好的,我收到了"。
-
**FIN**:挥手------"我要挂断啦"。
-
**RST**:掀桌子------"出问题了,重置连接吧"。
- **窗口大小(Window Size)**
- 就像收件人告诉快递员:"我一次最多能收 10 个包裹,别给太多哦!"
- **校验和(Checksum)**
- 检查包裹有没有破损,如果损坏,就像快递员要退回包裹。
三次握手
**建立连接的过程,就像交朋友前打招呼,确认对方是否愿意聊天。**
场景:两个人在电话上互相认识
- **第一次握手(请求连接)**
-
**客户端**:喂,你好,我想和你聊天!(发起 `SYN`)
-
*客户端发送请求,进入"等待回应"状态(SYN_SENT)。*
- **第二次握手(确认请求)**
-
**服务器**:喂,我听到了!我同意和你聊天!(发 `SYN+ACK`)
-
*服务器收到请求,进入"等待确认"状态(SYN_RECEIVED)。*
- **第三次握手(确认建立)**
-
**客户端**:好的,那咱们开始吧!(发 `ACK`)
-
*客户端确认连接,正式进入"聊天状态"(ESTABLISHED)。*
总结:
-
第一步:客户端发起请求------"我想聊聊!"
-
第二步:服务器回应------"好的,我愿意!"
-
第三步:客户端确认------"那我们开始!"
四次挥手
**结束连接的过程,就像两个人通完电话,依次挂断。**
场景:电话聊天结束
- **第一次挥手(发起挂断)**
-
**客户端**:我说完了,想挂电话了!(发 `FIN`)
-
*客户端表示自己不再发送数据了,进入"准备挂断"状态(FIN_WAIT_1)。*
- **第二次挥手(确认挂断)**
-
**服务器**:好的,我知道了,你准备挂吧!(发 `ACK`)
-
*服务器同意挂断,但还有话没说完,进入"等待完成"状态(CLOSE_WAIT)。*
- **第三次挥手(服务器也挂断)**
-
**服务器**:我也说完了,现在可以挂了!(发 `FIN`)
-
*服务器也准备挂断,进入"等待确认"状态(LAST_ACK)。*
- **第四次挥手(确认断开)**
-
**客户端**:好的,我知道你挂了,那我也挂了!(发 `ACK`)
-
*客户端确认挂断,彻底结束通话,进入"连接关闭"状态。*
总结:
-
第一步:客户端说------"我不说了,你慢慢说吧。"
-
第二步:服务器回------"行,那你等我说完。"
-
第三步:服务器说------"我也说完了,现在可以挂了。"
-
第四步:客户端回------"行,那挂了,拜拜!"
为什么不是二次握手和三次挥手?
- **三次握手不是二次握手:为了防止旧数据误导通信,确保双方确认连接正常。**
- 如果没有第三次确认,可能会误连接到旧的请求,导致通信失败。
- **四次挥手不是三次挥手:因为 TCP 是双向通信,双方需要独立关闭发送和接收,不能省略步骤。**
- 如果没有四次确认,可能会导致数据丢失或状态不同步。
-
**三次握手**:像打招呼,先确认对方身份,再开始聊天。
-
**四次挥手**:像挂电话,先告诉对方"我不说了",然后等对方也确认"我也说完了"。
-
**TCP关键字段**:快递单上的地址、页码、签收单,确保快递能顺利到达收件人手中!