TCP 收发数据流程

TCP如何收发数据

分段发送

可靠传输

  1. TCP 协议中,任何时候、任何一方都可以主动发送数据给另一方,为了解决数据报丢失、数据报错乱等问题,TCP 协议要求:接收方收到数据报后,必须对数据报进行确认!

    • seq:表示这次数据报的序号;
    • ACK:表示这次数据报是一个确认数据报;
    • ack:表示期望下一次接收的数据报序号;
  2. 发送方如果长时间没有收到确认数据报(ACK = 1),则会判定丢失或者是错误,然后重发;

连接的建立(三次握手)

  1. TCP 协议要实现数据的收发,必须要先建立连接,连接的本质其实就是双方各自开辟的一块儿内存空间,空间中主要是数据缓冲区和一些变量;

  2. 连接建立的过程需要经过三次数据报传输,因此称之为三次握手

    开始

    客户端:我说话能听见吗?

    服务器:能听见,我说话能听见吗?

    客户端:能听见

    结束

连接的销毁(四次挥手)

开始

客户端:我说完了,挂了?

服务器:我明白你说完了,但别忙挂,我还有话要说。

服务器继续说…

服务器:我也说完了,挂了?

客户端:好的!

结束

HTTP 和 TCP 的关系

  1. HTTP 协议是对内容格式的规定,它 使用TCP 协议完成消息的可靠传输;

  2. 在具体使用 TCP 协议时:

    1. 客户端发消息给服务器叫做请求,服务器发消息给客户端叫做响应;
    2. 使用 HTTP 协议的服务器不会主动发消息给客户端(尽管 TCP 可以),只对请求进行响应;
    3. 每一个 HTTP 请求-响应,都要先建立 TCP 连接(三次握手),然后完成请求-响应后,再销毁连接(四次挥手);这就导致每次请求-响应都是相互独立的,无法保持状态;

面试题

简述 TCP 连接的过程

TCP 协议通过三次握手建立可靠的点对点连接,具体过程是:

  1. 首先服务器进入监听状态,然后即可处理连接
    • 第一次握手:建立连接时,客户端发送 syn 包到服务器,并进入 SYN_SENT 状态,等待服务器确认;在发送的包中还会包含一个初始序列号 seq;此次握手的含义是客户端希望与服务器建立连接;
    • 第二次握手:服务器收到 syn 包,然后回应给客户端一个 SYN + ACK 包,此时服务器进入 SYN_RCVD 状态;此次握手的含义是服务端回应客户端,表示已收到并同意客户端的连接请求;
    • 第三次握手:客户端收到服务器的 SYN 包后,向服务器再次发送 ACK 包,并进入 ESTAB_LISHED 状态;
  2. 最后,服务端收到客户端的 ACK 包,于是也进入 ESTAB_LISHED 状态,至此,连接建立完成;

谈谈对四次挥手的理解

当需要关闭连接时,需要进行四次挥手才能关闭

  1. ClientServer 发送 FIN 包,表示 Client 主动要关闭连接,然后进入 FIN_WAIT_1 状态,等待 Server 返回 ACK 包;此后 Client 不能再向 Server 发送数据,但能读取数据;
  2. Server 收到 FIN 包后向 Client 发送 ACK 包,然后进入 CLOSE_WAIT 状态,此后 Server 不能再读取数据,但可以继续向 Client 发送数据;
  3. Client 收到 Server 返回的 ACK 包后进入 FIN_WAIT_2 状态,等待 Server 发送 FIN 包;
  4. Server 完成数据的发送后,将 FIN 包发送给 Client ,然后进入 LAST_ACK 状态,等待 Client 返回 ACK 包,此后 Server 既不能读取数据,也不能发送数据;
  5. Client 收到 FIN 包后向 Server 发送 ACK 包,然后进入 TIME_WAIT 状态,接着等待足够长的时间(2MSL)以确保 Server 接收到 ACK 包,最后回到 CLOSED 状态,释放网络资源;
  6. Server 收到 Client 返回的 ACK 包后便回到 CLOSED 状态,释放网络资源;

三次握手过程中可以携带数据吗?

  1. 第三次握手的时候,可以携带,前两次握手不能携带数据;

  2. 如果前两次握手能够携带数据,那么一旦有人想攻击服务器,那么他只需要在第一次握手中的 SYN 报文中放大量数据,那么服务器势必会消耗更多的时间和内存空间去处理这些数据,增大了服务器被攻击的风险。而对于第三次握手,此时客户端已经建立了连接,已经能够确认服务器的接收、发送能力正常,这个时候相对安全了,可以携带数据;

四次挥手等待 2MSL 的意义?

  1. 必须假想网络是不可靠的,有可能最后一个 ACK 丢失,所以 TIME_WAIT 状态就是用来重发可能丢失的 ACK 报文;

  2. Server 如果没有收到 ACK 将不断重复发送 FIN 片段,所以 Client 不能立即关闭,它必须确认 Server 接收到了该 ACK

  3. Client 会在发送出 ACK 之后进入到 TIME_WAIT 状态,如果直到 2MSLClient 都没有再次收到 FIN ,那么 Client 推断 ACK 已经被成功接收,则结束 TCP 连接;

挥手为什么要四次?

  1. 关闭连接时,当 Server 端收到 FIN 报文时,很可能并不会立即关闭连接,所以只能先回复一个 ACK 报文,告诉 Client 端,”你发的 FIN 报文我收到了”;

  2. 只有等到 Server 端所有的报文都发送完了,才能发送 FIN 报文,因此不能一起发送,故需要四步;

打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. TCP 收发数据流程
  2. 2. TCP如何收发数据
    1. 2.1. 分段发送
    2. 2.2. 可靠传输
  3. 3. 连接的建立(三次握手)
  4. 4. 连接的销毁(四次挥手)
  5. 5. HTTP 和 TCP 的关系
  6. 6. 面试题
    1. 6.1. 简述 TCP 连接的过程
    2. 6.2. 谈谈对四次挥手的理解
    3. 6.3. 三次握手过程中可以携带数据吗?
    4. 6.4. 四次挥手等待 2MSL 的意义?
    5. 6.5. 挥手为什么要四次?