更新于
2024-05-30 20:04:52
1. 运输层的作用
1.1 运输层的作用
TIP运输层向它上面的应用层提供通信服务,它是面向通信部分的最高层,是用户功能的最底层。
TIP网络通信的两个端点是两台主机的进程。
运输层一个很重要的作用是复用()和分用(。
运输层还需要对报文进行差错检测。
和一般的网络分层次一样,运输层为上层屏蔽了下面网络核心的细节,它使上层也只看见数据在两台主机的运输层平行传输。
定义 两个对等运输实体在通信时传送的数据单元叫做运输协议数据单元(Transport Protocol Data Unit)TPDU,对应在TCP/UDP协议下叫做TCP数据段()/UDP用户数据报。
1.2 运输层的端口
需要有一种和操作系统无关的方式来标识主机间的进程,这种方式也就是在运输层使用协议端口号(Protocol Port Number)。数据报被传送到某台主机运输层的端口上,接着由运输层完成分用,把该数据交给对应的进程。
的端口都使用位二进制数,端口号只具有本地意义,是应用层各个进程和运输层交互的一个层间接口。是一个软件接口。
其中叫做**熟知端口号(well-known port number)**或者系统端口号,固定分配给一些特定的应用进程。
而 叫做登记端口号,给没有熟知端口号的服务器进程使用
叫做短暂端口号,一般给客户端进程暂时动态选择使用。
2.
2.1 的特点
的特点主要有:
- 是无连接的协议,发送数据之前无需连接,也不需要关闭连接
- 是尽最大努力交付的,不保证可靠地交付
- 是面向报文的,每当上层交付一个数据报文,加上头部后就直接交付给层。不拆、不合并,不改变该数据报文的边界。每当从层接收一个数据报,去掉头部后就直接交给上层。一次交付一个完整的报文。
- 没有拥塞控制功能。
- 支持一对一、一对多、多对一、多对多的通信方式。
- 的头部开销非常小,只占**个字节**。
CAUTION由于面向报文,因此上层交给传输的报文必须要控制好大小。太大的报文在交给层时,层一定要经过分片,效率很低。太小的报文会使得报文首部的比例占比过大,导致传输效率不高。
TIP没有拥塞控制,这意味着即便网络拥塞时数据的传输速率也不会变小。一方面这对实时性应用进程是好事,但是另一方面没有拥塞控制的可能会引起网络的严重拥塞问题。
另外应用进程可以根据自己的需要,在传输层的上层为自行添加一些提高可靠性的措施。
2.2 报文的格式
报文的首部非常小,只有字节。
位数/字节数 | ||
---|---|---|
源端口 | ||
目的端口 | ||
长度 | 整个数据报的长度,最小值是字节 | |
校验和 | 加上伪首部的反码校验和,校验整个数据报 | |
伪首部 | 包括源IP,目的IP,0,17(协议字段),数据报长度 |
TIP当接收方发现数据报中的目的端口并不可达时,就会发送的目的不可达的差错报告报文。(下的)
CAUTION差错校验的方法和首部校验使用的方式都是一样的,都是用位对齐反码的方式求校验和,并且带上了数据部分,因此当数据部分不是16位的时候,要在后面补0,凑16位。
3.
3.1 的特点
的主要特点有:
- 是面向连接的,通信前需要建立连接,最后需要释放连接。
- 提供可靠的交付服务
- 面向字节流,而不是面向报文。即便应用进程和交互是一次一个数据块,但是只把这些数据视为一连串的无结构字节流。
- 拥有拥塞控制功能。
- 只支持点对点、一对一的通信(需要建立虚连接,有两个端点)。
- 头部有个字节。
- 提供的通信是全双工的。
CAUTION协议的每一个端口都设有发送缓存和接收缓存,因此理论上进程可以在想发送的时候就发送,发送时也可以接收,是一条全双工的通信链路。
每当进程要发送数据时就会将数据放入发送缓存,接着进程就可以继续做自己的事情,由在合适的时候发送。[可能是等缓存满了、操作、超时]
因而面向字节流的并不能保证接收方收到的数据块和发送方发送的数据块的划分是一样的,但是接收方收到的字节流和发送方发送的一定是一致的。
接收方的接收进程一定要能识别这个被重新划分的字节流。
3.1.2 的连接
把连接作为最基本的抽象。
的连接是端点到端点的连接。每一个端点都是一个套接字,因此一个连接也可以表示为:
也就是连接的四元组。
要建立的是可靠的通信信道,主要要实现的功能是:
- 信道不产生差错 [确认与重传机制]
- 发送方发送的数据接收方必须都能及时处理,(发送方和接收方的速度要匹配) [流量控制]
有一系列的协议用来解决这两个重要的问题。
3.2 报文的格式
即便面向字节流,但是的传送单元也还是数据报,有首部,也有数据部分。
位/字节数 | 说明 | |
---|---|---|
源端口 | ||
目的端口 | ||
序列号 | 该报文段的数据部分的第一个字节的序号。数据部分的每一个字节都按顺序编号。 | |
确认号 | 期待接收的下一个字符的顺序号。若顺序号,则表明前面到为止的字节都已经收到了 | |
数据偏移 | 标识数据字段的首部距离该报文段距离多少个4字节。表示范围是个字节。(60字节的最大首部长度) | |
紧急URG | 标识该报文是一个紧急报文,且此时紧急指针有效。等待队列里,会把紧急报文都插在一般报文的前面。 | |
确认ACK | 当时确认号字段才有效。当建立连接后,所有报文的ACK都要被置为1。 | |
推送PSH | 接收方收到的报文以后,会优先把此报文交给接收应用程序。 | |
复位RST | 用来标识连接出错,需要先释放连接再重新连接。也可以用来拒绝一个非法的报文,或者是拒绝一次连接请求。 | |
同步SYN | 用来建立连接。则为连接请求,则为连接接受。 | |
终止FIN | 用来终止连接。表示本方要发送的数据都已经发送完毕了。 | |
窗口 | 指示从该报文的确认字段号字节开始,对方(该报文的接收方)还能够发送字节的数据。 | |
校验和 | 校验和和一样加上字节的伪首部,协议字段改为。(如果使用,则伪首部也要改变)。校验方法使用二进制反码运算。伪首部如图。 | |
紧急指针 | 指出紧急数据的末尾在该报文中的位置/字节数(紧急数据都在一般数据之前),只有在时有效,且当窗口时也可以发送紧急数据! | |
选项 | 可变长,但一定是4字节的整数倍(否则填充)。 |
TIP选项字段可以增加的选项有:
- :单个报文数据部分的最大字节数,加上首部长度以后才会是报文的长度。在建立连接时,双方都把自己支持的写入报文段(可以不同),以后都按照这个传输。如果建立连接时没有选项,则默认字节。[因此每个主机能处理的报文段至少是]
- [3]: 报文首部的窗口字段默认是位,而有些特殊状况下(卫星通信)需要扩大窗口值来提高吞吐量,此时可以用此选项扩大窗口值,该选项用一个字节()来表示位移值,则窗口字段的位数改为位,支持的最大窗口值为。该选项也是在建立连接时协商,当不需要再使用窗口扩大以后,也可以利用该选项(设定为0)来取消窗口扩大。
- []: 选项中最主要的字段是
时间戳值字段
[和时间戳回送回答字段
[]
- 计算RTT: 如果发送方先发送一个带有时间戳字段的时间戳选项,接收方确认后,把这个时间戳字段复制到确认报文的时间戳选项的时间戳回送回答字段中返回给发送方,发送方根据这个字段就很容易算出一个的时间(当前时间- 时间戳回送回答字段值)。
- 防止序号绕回: 在报文里带上时间戳选项的时间戳字段,哪怕是当首部的序列号字段重复了(因为序列号是),也可以辨认的出这两个报文不是重复的报文。
- []:用来为**选择确认(Selective ACK)**机制提供服务。在建立连接时由双方协商是否使用选择确认选项。选择确认选项中用个字节表示出一个连续的字节块[个字节表示字节块起始位置的序列号,个字节表示出该字节块末位置的下一个字节的序列号],在使用另外的个字节表示该选项是一个选项,再使用另一个字节表示该选项总共占用多少字节。因此总共使用个字节。由于选项字段的最大长度是字节,因此一个字段最多可以表示个不连续的数据块。
3.3 可靠传输的实现方式
3.3.1 的重传机制
由于有超时重传机制,但是超多少时间才重传的时间很难确定。
过大导致接收方一直等待重传数据,空闲时间边长,效率很低
过小导致发送方不断进行不必要的重发,效率也很低。
希望这个仅仅只比往返时间稍微长一些。使用每一次往返报文的样本值来动态更新网络的往返时间:
一般取。
也是用该样本来更新往返时间的方差:
一般取。
重传时间就取:
但是考虑到一种特殊的报文: 重传报文。如果一报文的确认并未收到,于是重发。重发后收到确认信息。
该确认信息如果是重传报文的确认却被认为是最初报文的确认,则会导致该样本偏大,导致重传时间也偏大;但如果该确认信息是最初报文的确认却被认为是重传确认,则会导致该样本偏小,算出的重传时间也偏大了。判断该确认很麻烦,导致计算也很麻烦。
于是改进后的算法中对于重传报文的确认是这样使用的:
- 重传报文的样本一律不采用
但是又出现了一种情况: 网络状况突然变得很不好,所有报文都要重传!这又导致重传时间不会更新,所以整个网络一直处于重传中。。。
再次更新算法:
于是改进后的算法中对于重传报文的确认变成这样使用:
- 重传报文的样本一律不采用
- 每次重传以后,取,一般取。
实践证明,这样就合理了。。。
3.3.2 的发送/接收窗口
3.3.2.1 发送窗口
发送窗口指的是: 在没有接收到确认的情况下,能够发送出去的数据的字节数。
任何已经发送但是没有收到确认信息的数据,都要先放在发送方的发送缓存里。
接收方的接收窗口一定比发送方的发送窗口要小。
发送窗口有3个指针:
: 发送窗口后沿[]
: 第一个还没有发送的字节
: 发送窗口前沿[不能发送的第一个字节]
: 已经发送但还没有被接收的字节数
: 发送窗口大小
: 还可以发送但是尚未发送的字节数
发送窗口的后沿和发送缓存重合。(已确认的立刻删除)
发送窗口保存的是:
- 要发送但是还没发送的数据
- 已经发送但是没有收到确认的数据
3.3.2.2 接收窗口
接收窗口保存的是:
- 已经连续确认但是没有被读应用进程取走的数据
- 未按序到达确认的数据
接收方的每个确认值都是当前没收到的第一个字节的序号。
接收确认一般使用累积确认,这样可以减小网络传播开销。选择合适的时间把确认信息传递给对方,比如累积一定的确认、在发送自己的数据时捎带上确认信息。
3.3.3 的流量控制
的流量控制也是用接收窗口/发送窗口来控制。
CAUTION当接收方告诉发送方发送窗口时就不允许发送方在发送数据。但是万一要发送的数据仍然没有发送完毕,发送方就会一直以为发送窗口仍然是0,哪怕接收方已经处理好了缓存。
一个解决办法是: 设置一个0窗口等待计时器,当计时器计时结束后发送一个0窗口探测报文,接收方在对该探测报文的确认中给出自己的窗口值。非0则可以传送数据,为0则重置等待计数器!
:::tip thinking
由于报头至少是字节,数据报头又是字节,如果发送一个字节的数据,并且要求确认,线路上至少要传递 + [假设确认消息不需要发送数据部分]。如果要求接收方也要发送一个字节的确认数据,且不采用捎带确认和累积确认,则这一个字节的数据也需要共个字节,只传送一个字节则需要一共字节,个数据报。
但是如果使用捎带确认信息,则发送确认数据时可以把第一个数据报的确认也捎带,一共只需要个数据报,字节。
可见捎带确认和累积确认对减轻网络阻塞和提高利用率都很重要。
另外报文数据段也不宜太短,最好是累积一些数据以后再一起发送出去。
:::
发送方一般采用算法:
- 只有当前一个发送出去的数据报得到确认以后,再把缓存中的所有数据装成一个数据报发送出去。第一次只发送最初缓存中的第一个字节。
- 当数据已经达到窗口大小的一半或者最大长度时,就立刻发送一个数据报。
CAUTION考虑一种情况:网络速度很快但是接收方处理非常慢——糊涂窗口综合征
极端情况下每一次发送/确认(一个的时间),接收方只能处理个字节,确认信息中会告诉发送方只能有个字节的发送窗口,发送方就会每次只发送一个字节,造成传输效率不高。
有效的解决办法有:
- 先不发送数据,等待接收方处理一会数据[计时器]。
- 等接收方的缓存有至少一半空闲时才继续发送数据。