“生命在于运动,学习在于不断尝试。”——亚里士多德
文章目录
- 运输层概述与服务
- 运输层功能
- 运输层概述
- IP协议
- UDP和TCP协议
- 多路复用与多路分解
- UDP
- UDP相较于TCP的优点
- UDP报文段结构
- 检验和
- 可靠数据传输
- 构造可靠数据传输协议
运输层概述与服务
运输层为应用层提供了逻辑通信。从应用进程的视角来看,它们把数据送入运输层并从运输层获取数据。注意,运输层本身并不具备通信功能,它依靠它下层的网络层提供的服务来进行数据传输。
运输层功能
- 封装运输层报文组。运输层将从应用层送来的应用报文切割成小块以方便网络层进行发送,然后为每个小块封装上必要的信息,产生多个运输层报文段。
- 借助网络层传输数据。在第一章中介绍过,网络分为网络边缘和网络核心,应用层和运输层是网络边缘特有的。在运输数据时,运输层将报文段发送给同主机的网络层,由网络层通过调用它和它下面两层的服务进行传输数据。到了目的主机后,目的主机的网络层再将数据向上发送到运输层。
- 运输层为不同主机的进程提供逻辑通信,而网络层为不同主机提供逻辑通信。
- 网络层将一个主机产生的所有数据发送给另一个主机,实现主机与主机之间的通信。
- 运输层通过多路复用与多路分解,将来自其他主机的某个应用进程的数据精确的发送给该主机的某个应用进程,实现进程与进程之间的通信。
运输层概述
IP协议
IP协议是因特网的网络层协议,提供尽力而为交付服务,即只传输数据而对可靠性等没有任何保证。每台主机都有一个IP地址。经过网络层封装的报文称作数据报。
UDP和TCP协议
UDP和TCP是运输层的两个主要协议。
- UDP:一个非常简单的协议,只提供最基本的服务,比如多路复用与分解,比如完整性检查等。
- TCP:面向连接的运输层协议。提供可靠数据传输,拥塞控制等额外服务。
多路复用与多路分解
运输层采用多路复用和多路分解机制来与应用层交换数据。
第二章中介绍,运输层和应用进程之间通过套接字联系。通俗来讲,运输层收集所有套接字传来的信息,汇总,并发送给网络层,这个过程称为多路复用;这个过程的逆过程称为多路分解。
为了准确标识一个报文段从哪来,要到哪去,运输层报文段需要包含源端口号字段和目的端口号字段:
在UDP和TCP协议中的多路复用和多路分解有些不同:
- 在UDP协议中,一个套接字用一个二元组标识:目的主机IP地址和目的端口号。上图中的源端口号字段用于目的主机为源主机发送响应报文。
- 在TCP协议中,由于除欢迎套接字外的其他套接字都是专属于一个源主机和一个目的主机使用的,因此一个套接字用一个四元组标识:源主机IP地址,源端口号,目的主机IP地址,目的端口号。每个报文根据其源端口号字段和目的端口号字段被分解到连接套接字。
在Web服务器中,通常会为很多客户的TCP连接创建相应的连接套接字,有两种方式进行创建:
- 服务器为每个连接生成一个新进程,每个进程有一个连接套接字。
- 服务器只有一个进程,但为每个连接套接字创造一个新线程(轻量级的子进程)。这种做法往往是高效的,因为线程间传输数据的速度比进程快很多。
UDP
UDP运输层协议只提供最低限度的运输层服务。
UDP相较于TCP的优点
- 应用进程可以更精细的预测何时发送数据。由于TCP的拥塞控制机制,会把一些数据暂时留在源主机,这样的话就会造成延迟,UDP则没有这个问题。实时应用一般需要这种功能。
- 不建立连接。UDP无需建立连接,这使它无需遭受建立连接的时延,也不需要在端系统中维护连接状态,这使它能支持更多的客户连接。
- 分组首部开销小。TCP首部占20字节,UDP首部占8字节。
由于TCP和UDP各有优点,因此有一部分想要实现可靠数据传输但又不想受制于TCP拥塞控制机制的应用会采用UDP而且在应用层实现需要的额外服务。
UDP报文段结构
UDP报文段中,源端口号和目的端口号上文已经提过。
- 长度字段指明了报文段的长度
- 检验和字段提供了最基本的报文差错检测
检验和
检验和是差错检测的常用手段之一。它将报文段内所有16比特字的和进行反码运算。例如:
- 报文段中有三个16比特字:0110011001100000、0101010101010101、1000111100001100.
- 将三个比特字相加得到结果:0100101011000010
- 对这个结果取反码运算:1011010100111101,这个16比特字会被放入检验和。
UDP提供差错检测的原因是,相比于在网络核心的每一条链路上实现差错检测,只在端系统上实现这一功能是高效的(别忘记运输层只在端系统上部署),这也被称为端到端原则。
注意,即使UDP能发现差错,但它并不能实现差错恢复。
可靠数据传输
可靠数据传输服务使用运输层中的可靠数据传输协议实现。这个协议使得从应用进程角度来看,运输层能提供一条可靠的“通道”来传输数据。协议通过调用数个函数来实现:
- rdt_send():可靠数据传输函数。
- udt_send():网络层提供的不可靠数据传输函数。
- rdt_rcv():可靠数据接收函数。
- deliver_data():应用层接收运输层数据的函数。
构造可靠数据传输协议
我们使用**有限状态机(FSM)**来表述协议的功能。FSM是一种抽象结构,它只会在有限的几个状态间切换,且从一个状态切换到另一个状态需要一些特定的条件。
- rdt1.0:信道完全可靠的可靠数据传输传输协议。
底层信道可靠的情况下,协议只需要把信息送入信道并接受信息就可以了。如下图所示:
图中的两个FSM都只有一个状态,因此一直保持这个状态。横线上是状态的名称及开始传入的参数,横线下是这个状态实际采取的动作。
- make_pkt:以应用进程传入的数据data作为参数,将data打包成packet(分组)
- udt_send:直接将packet送入信道而不作其他处理。
- extract:将packet中的data取出来
- deliver_data:将data送入应用层
- rdt2.0:可能具有比特差错的信道的可靠数据传输协议。
在这种情况下,信道只会造成比特差错,而不会有其他问题。也就是说,只需要解决比特差错的问题就可以。
接收方通过发送给发送方肯定确认(ACK)来告知对方报文正确接收或通过否定确认(NAK)来告知对方报文出现问题。加入这种机制的协议称为自动重传请求(ABQ)协议。
在ABQ协议中,一般要有三个功能:
- 接收方需要知道这条报文出了差错。这需要差错检测功能,UDP中的检验和字段就是这个目的。
- 知道出了差错后,接收方要告知发送方这条报文有错。这需要接收方反馈功能,也就是上文讲的ACK和NAK。
- 发送方知道报文有错后,需要重新传一份同样的报文。这需要重传功能。
rdt2.0的RSM如下:
- 发送方中:
从虚线箭头开始,发送方通过和1.0一样的步骤发送报文,然后进入等待回应的状态。在等待回应时,如果发送方接收到回应(rdt_rcv函数)且回应是NAK(isNAK函数),那么再次发送一份同样的报文(udt_send函数)并保持当前状态;如果回应是ACK(isACK函数),那么切换到等待上层调用状态。 - 接收方中:
从虚线箭头开始,如果接收方收到了报文(rdt_rcv函数)但报文损坏了(corrupt函数),那么将NAK报文打包并发送给接收方;如果报文未损坏(notcorrupt函数),那么接收数据并打包一个ACK报文发送出去。
我是霜_哀,在算法之路上努力前行的一位萌新,感谢你的阅读!如果觉得好的话,可以关注一下,我会在将来带来更多更全面的知识讲解!