在七层的网络分层中,位于传输层的传输协议通常期望能够提供以下支持
- 保证讯息的传递
- 讯息传递顺序与发送顺序相同
- 一个讯息最多只会传输一份
- 支持任意大小的讯息
- 支持发送者与接受者的同步
- 允许接受者对发送者执行流量通知
- 支持一台主机上执行多个不同的应用程序
然而位于传输层下层的网络层具有以下限制
- 丢弃讯息
- 重新排序讯息
- 传递多份相同的讯息
- 传递的讯息有大小限制
- 讯息的传递可能有任意长短的时间延迟
总而言之,网络层提供的是不可靠的服务。传输层通讯协议的挑战在于将下层不可靠的网络层服务变成应用程序所需要的服务。
- 不可靠服务 -> 不可靠服务 (UDP)
- 不可靠服务 -> 可靠服务 (TCP)
UDP 协议
UDP 是一个不可靠的传输协议,它将下层的主机到主机的传输服务拓展成程序对程序的通讯服务,如下图所示。
UDP 通过增加一层反多工(demultiplexing),让同一个主机上的多个应用程序可以共享网络。UDP协议格式的首部有一个 DstPort 字段,不同的应用程序使用不同的 DstPort。
接收端主机在收到 UDP 封包之后,利用反多工获取 Port, 利用 Port 识别出该 UDP 封包属于哪个应用程序。
TCP 协议
和 UDP 相比,传输控制协议 TCP (Transmission Control Protocol) 提供以下服务
- 可靠的服务
- 面向连接
- 基于字节流的服务
同时 TCP 也有以下功能
- 流量控制 (Flow control)用来预防发送者发送过多的流量使接收者超出可负荷的容量
- 拥塞控制 (Congestion control)用来预防网络被注入过多的数据而导致路由器,交换机或者通信链路超出负荷
TCP 的资料段(Segments)
TCP 是一个基于字节流的通信协议,传送端将若干字节写入一个 TCP 连线,接收端从该 TCP 连线中读取字节。在 TCP 连线上传送的封包称为资料段(Segments)。
如下图所示,TCP 传送端将应用程序传送的字节先储存起来,等字节容量达到合理大小的资料段,再将这个资料段发送至 TCP 目的端主机。TCP 目的端会将资料段内容放入接收缓冲区,接收端应用程序再由此缓冲区读取字节
TCP 的连线管理
TCP 传送端与接收端在交换 Segments 之前需要先建立连线。Client 是连线启动者,在代码中通常是这样体现的。
Socket clientSocket = new Socket("hostname","port number");
Server 一直在等待 Client 连接,在代码中是这样体现的。
Socket connectionSocket = welcomeSocket.accept();
TCP 连线的建立采用三次握手(Three-way handshake)
- Client 发送 TCP SYN 资料段给 Server,注明 Client 一开始的序号
- Server 收到 SYN,回传 SYN/ACK 资料段,Server 配置缓冲区并注明 server 一开始的序号
- Client 收到 SYN/ACK,回传可能带有资料的 ACK 资料段
- SYN 标志位用于 TCP 建立连接
- Server 发送的 Acknowledgement = x + 1 表示 Client 发送的序号 x+1 之前的所有 segment, Server 都收到了,接下来 Client 可以发送序号为 x+1 的 segment 了。
- Client 发送的 Acknowledgement = y + 1 表示 Server 发送的序号 y+1 之前的所有 segment, Client 都收到了,接下来 Server 可以发送序号为 y+1 的 segment 了
SYN、FIN、RESET、PUSH、URG 和 ACK 是 TCP 协议首部的 6 bit 的标志位,用来传递 TCP 连线两端的控制讯息。SYN/FIN 标志位分别用于建立与终止 TCP 连接。
TCP 连线的关闭需要 4 次握手
Client 关闭 socket
clientSocket.close();
- Client 发送 FIN 给 Server
- Server 收到 FIN,回传 ACK。关闭连线,发送 FIN
- Client 接收 FIN, 回传 ACK,进入 “Timed wait” 状态
- Server 接收 ACK ,连线关闭
TCP Client 状态图
如上图所示,从 TCP Client 的角度来看连线的建立和关闭。
- TCP Client 最开始处于 CLOSED 状态
- TCP Client 准备初始化一个 TCP Connection
- TCP Client 发送 一个 SYN,进入 SYN_SENT 状态
- 收到 Server 的 SYN/ACK,发送 ACK,进入 ESTABISHED 状态,TCP 连接建立完成
- TCP Client 处于 ESTABISHED 状态,准备关闭连线
- TCP Client 发送一个 FIN,进入 FIN_WAIT_1 状态
- TCP Client 收到 Server 的 ACK, 进入 FIN_WAIT_2 状态
- TCP Client 收到 Server 的 FIN ,回送 ACK,进入 TIME_WAIT 专题,等待 30s,TCP Client 进入 CLOSED 状态
TCP Server 状态图
有 TCP Client 状态图,自然也有 TCP Server 状态图
- TCP Server 最开始处于 CLOSED 状态
- TCP Server 创建了一个 Socket 并监听 Socket,进入 LISTEN 状态
- TCP Server 收到来自 Client 的 SYN,回传 SYN/ACK,进入 SYN_RCVD 状态
- TCP Server 收到来自 Client 的 ACK,进入 ESTABLISHED 状态, Server 与 Client 的连线建立成功
- TCP Server 处于 ESTABISHED 状态,收到来自 Client 的 FIN,回传 ACK,进入 CLOSE_WAIT 状态
- TCP Server 发送 FIN,进入 LAST_ACK 状态
- TCP Server 处于 LAST_ACK 状态,收到来自 Client 的 ACK,进入 CLOSED 状态
总结
- 传输层的协议是讲主机之间的封包传递服务转换成应用程序之间的通讯管道
- UDP 提供不可靠的传输服务
- TCP 提供可靠的传输服务
参考
作为网络方面的简单入门内容,文章主要是介绍网络层协议的简单知识。这篇博客内容总结于黄能富教授的《CS01060 2017-秋季-計算機網路概論》课程,博客截图来源于课程 PPT。