关于CS144的小总结

文章目录

  • 字节流
  • 接收方需要完成的工作
    • 处理数据
    • 封装头部
  • 发送方需要完成的工作
    • 发送数据
    • 处理收到的报文段头部
      • 发送但未确认队列处理
      • 超时重传处理
  • 为什么需要三次握手
    • 角度1:确认连接双方能力
    • 角度2:避免半连接

字节流

接收方需要完成的工作

处理数据

  1. 交付:使用字节流的方式将数据交付上层,主要是lab1的实现内容,使用map维护乱序的碎片字符串来模拟数据接收缓冲区。
  2. seqno处理:接收到对方的报文中,获取其32b的seqno,解封装为64b的字节流中的index,以拼接到正确的位置

封装头部

  1. ackno计算:根据已经写入的64b字节流数量,封装为32b的ackno作为头部数据
  2. win计算:根据现在缓冲区的剩余长度作为win,封装为头部数据

发送方需要完成的工作

发送方主要有5种状态:

  1. CLOSED
  2. SYN_SENT
  3. SYN_ACKED
  4. FIN_SENT
  5. FIN_ACKED

第2、4、5种情况不需要再发送数据,第1种情况需要发送SYN报文,第3种情况需要从应用层取数据封装并发送

发送数据

  1. 从应用层取尽可能多的数据封装报文,不能超过报文最大长度和接收窗口大小
  2. 判断是否已经到达字节流结尾,决定是否发送FIN报文
  3. 将数据发送并存放到发送但未确认的队列中

处理收到的报文段头部

发送但未确认队列处理

TCP是累计确认,若ackno是新的,则将发送但未确认队列中的报文段末尾比ackno更早的都弹出,表示均已确认。

超时重传处理

  1. 若冗余ACK超过阈值或超时,则重传最早的发送未确认报文
  2. 若为冗余ACK,则进行冗余ACK计数;否则重启计数器,并重置超时时间为初始时间
  3. 若计数器超时,则超时时间加倍

为什么需要三次握手

三次握手流程如下,将发起连接的称为客户端,被连接方称为服务端。

  1. 客户端发送SYN报文,SYN位置1,且有ISN初始号作为序列号SEQ1。
  2. 服务端发送SYN_ACK报文,SYN和ACK位均置1,且有ISN初始号作为序列号SEQ2,ACKNO为SEQ1 + 1
  3. 客户端发送ACK报文,ACK位置1,且ACKNO为SEQ2 + 1

角度1:确认连接双方能力

参考链接
目的:双方均确认双方具有发送能力和接收能力。

  1. 客户端发送SYN报文并被服务端接收:此时服务端确认客户端有发送能力,服务端有接收能力。
  2. 服务端发送SYN_ACK报文并被客户端接收:自己发送的SYN报文被收到,确认自己发送能力和服务端的接收能力;能收到服务端的SYN_ACK报文,确认自己的接收能力和服务端的发送能力。因此第2次握手结束时,客户端就确认4个能力均具备了。
  3. 客户端发送ACK报文并被服务端接收:客户端收到了SYN_ACK报文,确认客户端具有接收能力和自己的发送能力。

第三次握手原因:如果没有第3次握手,则服务端无法确认本身的发送能力和客户端的接收能力。可能客户端根本无法接收。若在此时建立连接,则会造成资源浪费,发送报文也无法得到回应。

角度2:避免半连接

参考链接
TCP报文中均携带了确认号,若客户端因为网络拥塞,SYN报文很长时间才到达服务端,则客户端会超时重传SYN报文。然后客户端和服务端愉快地进行TCP之后结束连接。
而在结束后,客户端重发的SYN报文才到达,如果是2次握手,则服务端也会痛快地决定建立连接,给客户端发送信息,等待客户端的信息等等,浪费自身和网络资源。

你可能感兴趣的:(CS144,网络)