【USTC 计算机网络】第三章:传输层 - 传输层概述及其服务、多路复用与解复用、无连接传输:UDP

发布于:2025-03-25 ⋅ 阅读:(32) ⋅ 点赞:(0)

本文进入计算机网络第三章的内容:传输层。本章的目标是理解传输层的工作原理(多路复用/解复用、可靠数据传输、流量控制、拥塞控制)以及学习 Internet 的传输层协议(无连接传输的 UDP 协议与面向连接可靠传输的 TCP 协议)。传输层相关内容是整个计算机网络体系中最重要的部分,也是面试考核最多的部分。

本文首先概述了传输层及其服务,接着介绍了传输层如何通过多路复用与解复用实现在一条共享的物理信道上同时传输多个独立的数据流,最后介绍了无连接、不可靠的传输协议 UDP。

1. 传输层概述及其服务

​传输层位于网络层之上,应用层之下。​它主要负责在两台主机之间的应用进程之间提供端到端的(逻辑)通信服务,确保数据的可靠传输、顺序控制和差错检测。

传输层协议运行在端系统,发送方将应用层的报文分成报文段,然后传递给网络层,接收方将报文段重组成报文,然后传递给应用层。

传输层所提供的服务如下:

  • 端到端通信:传输层为运行在不同主机上的应用进程提供逻辑通信,使其能够相互发送和接收数据。​
  • 数据分段与重组:传输层将应用层的数据分割成适合网络层传输的段,并在接收端将其重新组装,确保数据完整性。​
  • 差错检测:通过在数据段中添加校验和,传输层能够检测数据在传输过程中是否发生错误。​
  • 流量控制:传输层通过控制数据发送速率,防止接收方的缓冲区溢出,确保数据的可靠接收。​
  • 拥塞控制:在网络出现拥塞时,传输层能够调整数据发送速率,以缓解网络压力,确保数据传输的稳定性。

传输层与应用层和网络层的联系与区别如下:

  • 应用层:应用层直接为用户的应用程序提供网络服务接口,它定义了应用程序之间通信的协议和数据格式。应用层协议建立在传输层协议之上,利用传输层提供的可靠数据传输服务,将数据交给传输层,传输层在逻辑上将数据传输到目的主机的应用进程。
  • 网络层:网络层提供的是主机之间的逻辑通信服务,负责在不同主机之间传输数据包,处理路由选择和寻址问题,如 IP 协议。传输层依赖于网络层提供的服务,网络层提供的数据传输服务(如延时、带宽)是传输层进行端到端数据传输的基础,传输层协议(如 TCP、UDP)在网络层提供的服务之上,增加了可靠性、流量控制等功能,以满足应用层的需求。

Internet 传输层协议分为 TCP 与 UDP:

  • 传输控制协议(Transmission Control Protocol,TCP):TCP 是一种面向连接的、可靠的、基于字节流的传输层协议,提供数据的可靠传输服务,包括数据顺序控制、流量控制和错误控制等功能。​
  • 用户数据报协议(User Datagram Protocol,UDP):UDP 是一种无连接的、非可靠的传输层协议,适用于对实时性要求较高的应用,如视频通话和在线游戏等。​

2. 多路复用与解复用

多路复用与解复用共同确保在一条共享的物理信道上能够同时传输多个独立的数据流,并在接收端准确地将这些数据分发到各自的目的地。

多路复用(Multiplexing)是指在发送端将来自多个源的数据流组合在一起,通过在数据中附加特定的标识信息(如端口号、序列号等),在同一物理信道上进行传输的技术。发送方主机从多个套接字接收来自多个进程的报文,根据套接字对应的 IP 地址和端口号等信息对报文段用头部加以封装,该头部信息用于接收方的解复用。

多路解复用(Demultiplexing)是接收端的过程,即在收到组合后的数据流后,根据数据包中的标识信息将数据拆分并分发给相应的应用进程。接收方主机根据报文段的头部信息中的 IP 地址和端口号将接收到的报文段发给正确的套接字(和对应的应用进程)。

多路解复用的工作原理详细地讲就是主机收到 IP 数据报时,每份 IP 数据报都有源 IP 地址目标 IP 地址,同时 IP 数据报会承载一个传输层报文段,报文段中都有源端口号目标端口号,主机联合使用 IP 地址和端口号确定相应进程的套接字发送报文。

TCP/UDP 报文段格式如下:

在这里插入图片描述

2.1 UDP 多路解复用

回顾一下之前讲过的 TCP/UDP 套接字编程,服务器在创建完套接字后将其绑定到了指定的 IP 地址与端口号上:

SOCKET serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));

客户端同理,只是我们没有显式地绑定,因为操作系统会自动分配一个可用端口,而且客户端会主动向服务器通信,发送消息时自己的端口是多少并不重要:

SOCKET clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

在 UDP 协议下每次发送消息都需要指定目标 IP 地址与目标端口号:

sendto(clientSocket, message, static_cast<int>(strlen(message)), 0, (sockaddr*)&serverAddr, sizeof(serverAddr));

当某个主机接收到 UDP 数据报时,首先假设网络层已经保证当前这个数据报的目标 IP 地址就是本机,那么主机这时候需要检查数据报的目标端口号,根据二元组 (目标IP, 目标Port) 查找对应的本地 UDP Socket 是哪个,将数据报定位给对应的套接字。

2.2 TCP 多路解复用

客户端的 TCP 套接字需要向服务器建立连接:

connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));

服务器的 TCP 套接字需要监听等待并接受来自客户端的连接:

listen(serverSocket, SOMAXCONN);
SOCKET clientSocket = accept(serverSocket, (sockaddr*)&clientAddr, &clientAddrLen);

连接建立后服务器创建一个新套接字用来与客户端通信,这个套接字由四元组 (源IP, 源Port, 目标IP, 目标Port) 唯一确定。当某个主机接收到 TCP 报文段时,服务器不仅需要检查报文段的目标端口号,还需要检查源 IP 地址和源端口号,根据四元组的信息定位对应的本地 TCP Socket。由于 TCP 套接字不仅仅由本地的 IP 与端口号唯一确定,因此服务器能够在一个 TCP 端口上同时支持多个 TCP 套接字。

3. 无连接传输:UDP

3.1 介绍

UDP,即用户数据报协议(User Datagram Protocol),是传输层的核心协议之一,UDP 是一种无连接不可靠的协议。它的设计目标是提供低延迟低开销的数据传输服务,适合那些对实时性要求高,但对可靠性要求较低的应用场景。

UDP 的基本特性如下:

  • 无连接性:UDP 在数据传输前不需要建立连接,不存在握手过程,因此传输前开销极低,每个数据包(数据报)都是独立的。
  • 不保证可靠性:UDP 提供“尽力而为”服务,不保证数据的到达、顺序或完整性。传输过程中可能会丢失、重复或者乱序,但这正是为了减少协议本身的开销。
  • 报文边界保留:UDP 是一种面向报文的协议,发送方每次发送一个数据报,接收方接收到的数据报与发送时保持相同的边界,不会像 TCP 那样将数据流重新分段。
  • 简单高效:UDP 的头部结构简单,总长度只有 8 字节,包含了源端口、目的端口、长度和校验和等字段。这种简单性使得 UDP 在处理数据时所需的计算资源非常少,适合要求低延迟的场合。

3.2 UDP 数据报格式

UDP 数据报的头部总共 8 个字节,具体字段如下:

  • 源端口(Source Port,16 位):表示发送端的端口号。该字段可选,若不需要回传数据,可设为 0。
  • 目的端口(Destination Port,16 位):指定接收端的端口号,用于将数据交给正确的应用进程。
  • 长度(Length,16 位):表示整个 UDP 数据报(头部加数据)的长度,最小值为 8 字节。
  • 校验和(Checksum,16 位):用于对 UDP 头部和数据进行错误检测,确保数据在传输过程中没有发生破坏。虽然 UDP 是无连接的,但校验和的作用可以帮助接收方验证数据完整性。

在这里插入图片描述

3.3 校验和

校验和的主要作用在于对传输过程中的数据完整性进行检测,尽管 UDP 本身不提供可靠性保证,但校验和可以帮助接收方发现数据报在传输过程中是否出现了比特级错误。

UDP 校验和不仅对 UDP 头部和数据部分进行校验,还需要包含一个伪头部(Pseudo Header)。伪头部并非真正发送在网络上的数据,但在校验和计算时必须加以考虑,其内容包括:

  • 源 IP 地址:发送方的 IP 地址;
  • 目的 IP 地址:接收方的 IP 地址;
  • 协议类型:对于 UDP 来说,其值为 17(0x11);
  • UDP 长度:整个 UDP 数据报(头部和数据)的总长度。

通过加入伪头部,校验和能够覆盖 IP 层的一部分信息,从而降低了错误发生时数据误投的风险。

UDP 校验和的计算通常采用一补码求和(One’s Complement Sum)的方法,主要步骤如下:

  • 把 UDP 头部、数据部分以及伪头部分成若干个 16 位的字。如果数据的字节数为奇数,则在末尾补零。
  • 使用一补码加法(即每次加法中如果最高位发生进位,将进位值加回到结果中)对所有 16 位字进行累加。
  • 将累加结果的每一位取反(即求一补码),得到最终的校验和值。
  • 如果计算结果为全零(即 0x0000),在某些实现中会将其置为 0xFFFF,以避免校验和值为零表示不进行校验的情况。

当接收方对收到的数据重新计算校验和时,如果结果不为 0xFFFF(在一补码运算中,正确的校验和结果应为全 1),则说明数据可能被破坏。

在这里插入图片描述

校验和并不能保证检测出所有传输错误,即使计算出的校验和正确,数据中仍可能存在未被检测出的错误,这些错误称为残存错误

当多个错误同时发生时,其影响在求和过程中可能互相抵消,导致最终的校验和不变。虽然残存错误的概率通常很低,但并非为零,这也是为什么在对可靠性要求更高的场景下,会采用更复杂的错误检测(甚至纠正)机制,比如 CRC(循环冗余校验)或 FEC(前向纠错)。


网站公告

今日签到

点亮在社区的每一天
去签到