当我们的应用程序需要在不同的计算机之间通信时,我们需要使用传输层服务和协议。传输层协议是运行在计算机上的软件,用于将应用程序消息分段,并在网络上传输这些消息。接收方计算机在接收到这些分段后,会将它们重新组装成原始的应用程序消息,并将它们传递给应用层处理。
在互联网中,有两个主要的传输协议:TCP 和 UDP。TCP 提供可靠的、面向连接的传输服务,可以确保应用程序消息的完整性和可靠性。UDP 则提供了简单的、无连接的传输服务,适合一些对数据可靠性要求不高的应用程序。在编写应用程序时,我们可以根据需要选择使用 TCP 或 UDP 进行数据传输。
计算机网络中,通信需要在多个层次进行。
- 网络层是在不同主机之间进行通信的层
- 传输层则是在主机内部的不同应用程序进程之间进行通信的层。
- 传输层依赖于网络层提供的服务,同时也增强了网络层的服务能力,实现了应用程序进程之间的可靠通信。
- 通过传输层,不同主机上的应用程序可以通过网络层提供的逻辑通信实现互相传输数据。
通过一个家庭类比来解释计算机网络的层次结构。我们可以将一个家庭视为一个主机:
- 家庭中的孩子们则是主机中的进程。
- 信件是应用程序中的消息
- 将信件分发给家庭中的孩子则相当于传输协议的工作
- 将信件送到对方家庭则类似于网络层协议的工作,就像邮政服务一样。
互联网传输层使用的两种协议:
- TCP,它提供了可靠的、有序的数据传输,并实现了拥塞控制、流量控制和连接建立等功能。
- UDP,它提供了不可靠的、无序的数据传输,相当于在IP层的基础上增加了一些简单的功能。
- 这两种协议都不能保证数据传输的延迟和带宽。
- 多路复用是指在发送端,将来自多个应用程序的数据打包在一起,并加上一个头部信息,以便在接收端进行多路解复用。
- 多路分用则是指在接收端,根据头部信息将数据解包并交付给正确的应用程序。
- 可以将多路复用比作将多个人的包裹打包成一个大的包裹并标记好收件人和地址,而多路分用就像是根据标记将大包裹拆分成小包裹并送到正确的收件人那里。这样可以确保数据能够正确、高效地传输。
-
当数据从源主机发送到目标主机时,数据会被分成多个数据包进行传输,每个数据包会被分配一个源IP地址和目标IP地址,这些地址用于确定数据包的路由和目的地。同时,每个数据包中还会携带一个传输层的数据段,其中包含源端口号和目标端口号。端口号用于将数据包传递到正确的应用程序,因为在同一主机上可能有多个应用程序在同时进行数据通信。
-
接收方主机会使用数据包中的IP地址和端口号将数据包传递到正确的套接字,套接字是应用程序和传输层之间的接口,它用于接收和发送数据。通过使用IP地址和端口号,主机可以将数据包分配给正确的套接字,并确保数据被正确传输和接收。

当我们在一个主机上创建一个UDP socket时,系统会为该socket分配一个本地端口号,用来标识该socket。
当我们要发送一个UDP数据包时,需要指定目标IP地址和端口号。
当主机收到UDP数据包时,会检查数据包中的目标端口号,然后将数据包分配给对应的本地端口号的socket,这样就可以将数据包正确地交付给相应的应用程序处理。
多个具有相同的目标端口号但不同的源IP地址或源端口号的数据包将被分配给同一个socket来处理。

- TCP套接字(socket)由4元组标识:
- 源IP地址
- 源端口号
- 目标IP地址
- 目标端口号
- 多路分用:接收方使用这四个值将段(segment)定向到适当的套接字上
- 服务器主机可能支持许多同时的TCP套接字:
- 每个套接字由其自己的4元组标识
- web服务器为每个连接的客户端使用不同的套接字
- 非持久性HTTP将为每个请求使用不同的套接字

用户数据报协议(UDP)是一种互联网传输协议,被称为“不加装饰的”或“基本的”传输协议。
- UDP提供了一种“尽力而为”的服务,也就是说,它不能保证传输数据的可靠性,因为UDP数据报可能会丢失或以错乱的顺序到达应用程序。
- UDP是一种无连接的协议,发送方和接收方之间没有握手过程。
- 每个UDP数据报都是独立处理的,而不依赖于其他数据报。
UDP主要应用于流媒体应用程序(能容忍数据丢失,对数据传输速率敏感)、DNS(域名系统)和SNMP(简单网络管理协议)等场景。
- 如果需要可靠的数据传输,则需要在应用层添加一些错误恢复机制,这些机制通常是特定于应用程序的。

UDP协议的优点:
- 不需要进行连接建立,这可以减少一些延迟
- 设计非常简单,不需要在发送方和接收方维护连接状态
- UDP的报头很小,可以减少一些开销
- UDP没有拥塞控制,可以随意发送数据,适合在需要快速传输的情况下使用
在传输数据时,可能因为信号干扰导致某些比特位被翻转。发送方将数据段看作是一系列16位整数,并对这些整数进行求和操作,得到一个校验和(checksum)。发送方将这个校验和值放入UDP数据段的校验和字段中。接收方在收到数据段后也对其进行校验和操作,并将计算得到的校验和值与发送方发送的校验和值进行比较。
- 如果两个值相同,则说明数据段在传输过程中没有发生错误;
- 如果两个值不同,则说明数据段在传输过程中出现了错误。
- 但是即使计算出的校验和值与发送方发送的校验和值相同,也不能保证数据段没有错误。
包括以下三个部分:
- 伪首部(Pseudo head)
- UDP头(UDP head)
- 应用数据(Application data)

伪首部是在UDP检验和计算中使用的一种数据结构,用于增强UDP检验和的可靠性。它不是UDP头的一部分,而是在计算UDP检验和时添加到UDP头前面的一段虚构的头部。
伪首部中包括了源IP地址、目的IP地址、协议类型、UDP报文长度等信息,它们是用来保证在传输过程中UDP数据报不被篡改和丢失的。由于UDP没有像TCP那样的确认机制,因此伪首部是在保证UDP数据报传输可靠性方面的重要手段。

注意:在加法中,如果最高有效位有进位,则需要将其加到结果中。
可靠数据传输的原则在应用层、传输层和链路层中都非常重要。这是网络中最重要的十个主题之一!

-
rdt_send():由上层调用(例如,应用程序)。传递数据以传递到接收方上层。
-
udt_send():由rdt调用,将数据包通过不可靠信道传输到接收方。
-
deliver_data():由rdt调用,将数据传递给上层。
-
rdt_rcv():当数据包到达信道的接收端时调用。
不可靠的信道特性将影响可靠数据传输协议(rdt)的复杂程度。
接下来我们要:
- 逐步构建可靠数据传输协议(rdt)的发送方和接收方
- 仅考虑单向的数据传输
- 但是控制信息会在两个方向上流动。
- 使用有限状态机(FSM)来描述发送方和接收方的行为。在状态机中,每个状态的下一个状态都是由下一个事件唯一确定的。当一个事件发生时,它会导致当前状态转换到下一个状态。在状态转换期间,会执行一系列操作。

- 基础信道完全可靠
- 没有位错误
- 没有数据包丢失
- 发送方和接收方分别使用有限状态机
- 发送方将数据发送到底层信道
- 接收方从底层信道读取数据

- 信道中可能存在比特错误
- 使用校验和来检测数据包中是否出现错误。
- 如何从这些错误中恢复:
- 当接收方收到数据包时,会发送确认(ACK)消息告诉发送方数据包已经接收
- 如果数据包有错误,则会发送否定确认(NAK)消息。
- 发送方在收到NAK时会重新发送数据包。
- 这些机制称为自动重传请求(ARQ)协议
- 在rdt2.0中,相比rdt1.0,引入了新的机制:
- 错误检测
- 反馈机制(ACK、NAK消息)
- 重传











