文章目录
- 字节流
- 接收方需要完成的工作
- 处理数据
- 封装头部
- 发送方需要完成的工作
- 发送数据
- 处理收到的报文段头部
- 发送但未确认队列处理
- 超时重传处理
- 为什么需要三次握手
- 流程
- 角度1:确认连接双方能力
- 角度2:避免半连接
- 为什么需要4次挥手
- 流程
- 4次挥手的目的
- 为什么4次挥手就能满足以上目的
字节流
接收方需要完成的工作
处理数据
- 交付:使用字节流的方式将数据交付上层,主要是lab1的实现内容,使用map维护乱序的碎片字符串来模拟数据接收缓冲区。
- seqno处理:接收到对方的报文中,获取其32b的seqno,解封装为64b的字节流中的index,以拼接到正确的位置
封装头部
- ackno计算:根据已经写入的64b字节流数量,封装为32b的ackno作为头部数据
- win计算:根据现在缓冲区的剩余长度作为win,封装为头部数据
发送方需要完成的工作
发送方主要有5种状态:
- CLOSED
- SYN_SENT
- SYN_ACKED
- FIN_SENT
- FIN_ACKED
第2、4、5种情况不需要再发送数据,第1种情况需要发送SYN报文,第3种情况需要从应用层取数据封装并发送
发送数据
- 从应用层取尽可能多的数据封装报文,不能超过报文最大长度和接收窗口大小
- 判断是否已经到达字节流结尾,决定是否发送FIN报文
- 将数据发送并存放到发送但未确认的队列中
处理收到的报文段头部
发送但未确认队列处理
TCP是累计确认,若ackno是新的,则将发送但未确认队列中的报文段末尾比ackno更早的都弹出,表示均已确认。
超时重传处理
- 若冗余ACK超过阈值或超时,则重传最早的发送未确认报文
- 若为冗余ACK,则进行冗余ACK计数;否则重启计数器,并重置超时时间为初始时间
- 若计数器超时,则超时时间加倍
为什么需要三次握手
流程
三次握手流程如下,将发起连接的称为客户端,被连接方称为服务端。
- 客户端发送SYN报文,SYN位置1,且有ISN初始号作为序列号SEQ1。
- 服务端发送SYN_ACK报文,SYN和ACK位均置1,且有ISN初始号作为序列号SEQ2,ACKNO为SEQ1 + 1
- 客户端发送ACK报文,ACK位置1,且ACKNO为SEQ2 + 1
角度1:确认连接双方能力
参考链接
目的:双方均确认双方具有发送能力和接收能力。
- 客户端发送SYN报文并被服务端接收:此时服务端确认客户端有发送能力,服务端有接收能力。
- 服务端发送SYN_ACK报文并被客户端接收:自己发送的SYN报文被收到,确认自己发送能力和服务端的接收能力;能收到服务端的SYN_ACK报文,确认自己的接收能力和服务端的发送能力。因此第2次握手结束时,客户端就确认4个能力均具备了。
- 客户端发送ACK报文并被服务端接收:客户端收到了SYN_ACK报文,确认客户端具有接收能力和自己的发送能力。
第三次握手原因:如果没有第3次握手,则服务端无法确认本身的发送能力和客户端的接收能力。可能客户端根本无法接收。若在此时建立连接,则会造成资源浪费,发送报文也无法得到回应。
角度2:避免半连接
参考链接
TCP报文中均携带了确认号,若客户端因为网络拥塞,SYN报文很长时间才到达服务端,则客户端会超时重传SYN报文。然后客户端和服务端愉快地进行TCP之后结束连接。
而在结束后,客户端重发的SYN报文才到达,如果是2次握手,则服务端也会痛快地决定建立连接,给客户端发送信息,等待客户端的信息等等,浪费自身和网络资源。
为什么需要4次挥手
流程
四次握手流程如下:假设数据先发送完毕的是客户端
- 客户端数据发送完毕,发送FIN报文
- 服务端针对1的FIN发送ACK报文
- 服务端数据发送完毕,发送FIN报文,此报文携带2报文中的ACK确认号
- 客户端针对2的FIN发送ACK报文
注意点:服务端收到ACK后可立即关闭连接,而服务端在发送完ACK后不能立即关闭连接,需要等待一段时间后,未再收到服务端的报文,才能关闭连接。
4次挥手的目的
目的:
每个TCP实体都既作为发送方,也作为接收方
a. 作为发送方:确认【对方已收到所有报文】
b. 作为接收方:确认【对方确认[自己已收到所有报文]】
为什么4次挥手就能满足以上目的
作为晚结束的那一方(如以上流程中的服务端),在收到4后就满足a,并满足了b,为什么呢?因为3报文中也携带着对客户端FIN报文的ACK确认号,当服务端收到了4报文,则服务端确认客户端收到了3报文,则满足b。
作为早结束的那一方(如以上流程中的客户端),收到2的ACK就满足a,在设定时间内未收到服务端反馈则认为满足了b,为什么呢?若服务端未收到4报文,则会超时重传,要求客户端重新发送4报文;若服务端收到4报文则直接关闭连接。客户端在足够长的时间未收到服务端的超时重传报文,则认为服务端已关闭连接,即客户端是通过服务端连接已关闭来满足b条件的。
我认为这个小结是4次握手的本质原因,洞察4次挥手的目的。