Boo's Blog

Stay foolish, Stay hungry

什么是 TCP?

TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。

  • 面向连接:一定是『一对一』才能连接,不能像 UDP 协议可以一个主机同时向多个主机发送消息,也就是一对多无法做到。
  • 可靠的:无论网络链路中出现了怎样的链路变化,TCP 都可以保证一个报文一定能够到达接收端。
  • 字节流:消息是『没有边界』的,所以无论我们消息有多大都可以进行传输。并且消息是『有序的』,当『前一个』消息没有收到的时候,即使它先收到了后面的字节,那么也不能扔给应用层去处理,同时对『重复』的报文会自动丢弃。

简述三次握手过程:

  • 第一次握手,客户端给服务发送一个 syn 包,等待服务端确认
  • 第二次握手,当服务端受到请求之后,此时要给客户端一个确认信息 ack,并同时发送 syn 包,等待客户端确认
  • 第三次握手,客户端受到服务端发送的 ack + syn 包之后,向服务端发送 ack

为什么 TCP 握手是三次,不是两次或者四次?

因为三次握手才能保证双方具有接收和发送的能力。这个回答没有问题,但是比较片面,没有说出主要原因。

不使用「两次握手」和「四次握手」的原因:

  • 「两次握手」:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;
  • 「四次握手」:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。

四次挥手过程:

  • 客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户 端进入 FIN_WAIT_1 状态。
  • 服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSED_WAIT 状态。 客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
  • 等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入状态。
  • 客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 状态
  • 服务器收到了 ACK 应答报文后,就进入了状态,至此服务端已经完成连接的关闭。
  • 客户端在经过 2MSL 一段时间后,自动进入 状态,至此客户端也完成连接的关闭。

可以看到,每个方向都需要一个 FIN 和一个 ACK,因此通常被称为四次挥手。

为什么要四次挥手?

两次握手就可以释放一端到另一端的 TCP 连接,而完全释放连接则一共需要四次握手。

TCP 和 TDP 区别:
1. 连接

  • TCP 是面向连接的传输层协议,传输数据前先要建立连接。
  • UDP 则不需要建立连接,即刻传输数据。

2. 服务对象

  • TCP 是一对一的两点服务,即一点连接只有两个端点
  • UDP 支持一对一、一对多、多对多的交互通信

3. 可靠性

  • TCP 是可靠交付数据的,数据可以无差错、不丢失、不重复、按需到达
  • UDP 是尽最大努力交付,不保证可靠交付数据

4. 拥塞控制、流量控制

  • TCP 有拥塞控制和流量控制机制,保证数据传输的安全性
  • UDP 则没有,即使网络非常拥堵了,也不会影响 UDP 的发送速率

5. 首部开销

  • TCP 首部⻓度较⻓,会有一定的开销,首部在没有使用「选项」字段时是 20 个字节,如果使用了「选项」 字段则会变⻓的。
  • UDP 首部只有 8 个字节,并且是固定不变的,开销较小。

6. 传输方式

  • TCP 是流式传输,没有边界,但保证顺序和可靠。
  • UDP 是一个包一个包的发送,是有边界的,但可能会丢包和乱序。

7. 分片不同

  • TCP 的数据大小如果大于 MSS 大小,则会在传输层进行分片,目标主机收到后,也同样在传输层组装 TCP 数据包,如果中途丢失了一个分片,只需要传输丢失的这个分片。
  • UDP 的数据大小如果大于 MTU 大小,则会在 IP 层进行分片,目标主机收到后,在 IP 层组装完数据,接着再 传给传输层,但是如果中途丢了一个分片,在实现可靠传输的 UDP 时则就需要􏰂传所有的数据包,这样传输 效率非常差,所以通常 UDP 的报文应该小于 MTU。

评论