TCP

TCP (Transmission Control Protocol) 是一种传输层通信协议。

在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。

不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。

TCP 传输过程

一个典型的传输过程,就是一个对数据的逐层封装:

  • 一、应用层向传输层发送用于网间传输的、用8位字节表示的数据流(Stream)。

    用户数据
  • 二、传输层的 TCP 把数据流分割成适当长度(受所处网络的数据链路层 MTU 限制)的报文段(segment)。

    TCP 头 用户数据
  • 三、TCP 把结果传给网络层。网络层的 IP 将报文段封装成数据报(Datagram)。

    IP 头 TCP 头 用户数据
  • 四、IP 层再将数据报交由数据链路层封装成帧(Frame)用于发送。

    帧头 IP 头 TCP 头 用户数据 帧尾
  • 五、通过物理层传输数据。

接受端对数据的操作是个反向操作,称为解封装,逐层移除头信息。

TCP 连接创建(三次握手 three-way handshake)

建立一个 TCP 连接,需要经过三次握手:

  1. SYN:客户端选择一个随机序列号 x ,发送一个 SYN 分组(可包含其他TCP标志、选项)。

  2. SYN ACK:服务端给 x 加 1 ,同时自身选择一个随机序列号 y ,返回响应(可包含其他TCP标志、选项)。

  3. ACK:客户端给 x、y 加 1,发送 ACK 分组。

    客户端可以在发送完该分组后立即发送数据,服务端则需要接收到该分组之后才能开始发送数据

经过这三次握手之后,连接就创建了。

三次握手会带来很大的延迟。因此建立连接是个性能开销很大的操作。

为什么建立链接使用三次握手

有创建链接的两个角色:客户端(下称 C)服务端(下称 S),想象以下交互场景:

第一步,C 发送给 S:“S,你能收到吗?” 做了这一步之后:

  • C 不知 S 能否能接收、发送
  • S 知道 C 能发送,不知 C 能否接收

第二步,S 发送给 C:“C,我收到了,你也能收到吗?” 做了这一步之后:

  • C 知道 S 能接收,也知道 S 能发送
  • S 知道 C 能发送,不知 C 能否接收

第三步,C 发送给 S:“S,我也收到了,我们都能收到和发送,那就开始说正事啦…” 做了这一步之后:

  • C 知道 S 能接收,也知道 S 能发送
  • S 知道 C 能发送,也知道 C 能接收

经过以上三步,C 与 B 都确认了对方可以接收和发送,因此,一个双向的通道得到确认。

三次握手实质是两个方向各一次问询和各一次确认共四次交互,只是中间两次(确认+问询)可以合并优化成三次。

三次握手甚至更多次握手都无法确保链接的绝对可靠,因为最后一个包总有可能丢失…可以参考“两军问题”。在上面的例子中,客户端 C 在第三步发送的包可能是丢失的,所以,单纯靠三次握手是不能保证可靠的,需要其他的机制来实现。

总的来说,三次握手是在尽可能可靠和尽可能高效中取得平衡的折中做法。

TCP 传输数据

在TCP的数据传送状态,很多重要的机制保证了TCP的可靠性和强壮性。

  • 使用序号 对收到的TCP报文段进行排序以及检测重复的数据

  • 使用校验和 TCP用一个校验和函数来检验数据是否有错误,在发送和接收时都要计算校验和。

  • 使用确认和计时器 收端实体对已成功收到的包发回一个相应的确认(ACK), 如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。

TCP 连接断开(四次握手 four-way handshake)

整理中…