0
点赞
收藏
分享

微信扫一扫

计算机网络——运输层

青青子衿谈育儿 2022-04-06 阅读 128

运输层

运输层协议概述

网络层为主机之间提供逻辑通信,而运输层为应用进程之间提供提供端到端的逻辑通信。

端口:

16位端口号,只具有本地意义,分为两类

  1. 服务器端使用的端口号。又分为熟知端口号和登记端口号
  2. 客户端使用的端口号,又叫短暂端口号,留给客户进程选择短暂使用。

用户数据报协议UDP

特点

  1. 无连接:发送前不需要建立连接。
  2. 尽最大努力交付。
  3. 面向报文的。应用层交给UDP多长报文,UDP照样发送。
  4. 没有拥塞控制。网络的拥塞不会使源主机的发送速率降低。
  5. 支持一对一,一对多,多对一和多对多。
  6. 首部开销小。只有8字节,TCP20 字节。

首部格式

四个字段都是2字节。

UDPshoubu

如果接收方发现目的端口不正确就丢弃该报文,并且发送ICMP端口不可达报文给发送方。

伪首部是为了计算检验和,不会发送,UDP的检验和是把首部和数据部分一些检验。

检验和的方法:

  1. 先全0填充
  2. 连同伪首部每16位分割,数据部分不足偶数的补零字节。
  3. 二进制反码求和(先取反然后求和)。将和的反码写入检验和字段。
  4. 发送方收到的报文二进制反码求和,无差错时结果应为全1.

传输控制协议TCP概述

主要特点

  1. 面向连接的运输层协议
  2. 每一条连接只能有两个端点,点对点。
  3. 提供可靠交付,按序,无差错
  4. 提供全双工通信。任何时候都能发送数据,设有发送缓存和接收缓存
  5. 面向字节流。流入到进程或从进程流出的字节序列。TCP把应用程序交下来的数据仅仅看成一连串的无结构的字节序列。TCP不保证接收方进程收到的数据块和发送方的数据库具有对应大小的关系

TCP的连接

套接字:TCP连接的端点。端口号拼接到IP地址就构成了套接字。

​ 套接字 socket =(IP地址:端口号)

每一条TCP连接唯一的被通信两端的套接字确定。

首部格式

TCPshoubu

  1. 源端口和目的端口:

  2. 序号:字节流中的每一个字节按顺序编号。指的是本报文段发送数据的第一个字节号。

  3. 确认号:期望收到对方下一个报文段的第一个字节序列号。若确认号为N,表面到序号N-1的数据全部正确收到。

  4. 数据偏移:单位是32位,表示数据报文相对报文段的起始处有多远,即首部长度

  5. 6个控制位

    • 紧急URG:为1表示此报文段有紧急数据,需尽快发送。把紧急数据插入到本报文段的最前面,与首部的紧急指针字段配合使用。
    • 确认ACK:为1时首部的确认号字段才有效。规定建立连接之后必须置1。
    • 推送PSH:发送方PSH置1,立即创建一个报文段发送出去;接收方收到尽快交付给进程
    • 复位RST:连接中出现严重差错,释放连接再重新建立。
    • 同步SYN:为1表示这是一个连接请求或连接接受报文段。
    • 终止FIN:为1表示是释放连接报文段。
  6. 窗口:现在允许对方发送的数据量。作为接收方让发送方设置其发送窗口的依据。

  7. 检验和:同UDP,计算时要加上伪首部。

  8. 紧急指针:指出紧急数据末尾在报文段中的位置(紧急数据结束后就是普通数据),即使窗口为0也可发送紧急数据。

  9. 选项:最长40字节。

    • 窗口扩大选项:窗口的位数扩大,由16扩大到16+S ,S 最大为14。

    • 时间戳选项:主要是时间戳值和时间回送回答字段。用来计算往返时间RTT和TCP序号超过2^32的情况

    • 选择确认选项

MSS最大报文段长度:TCP报文段长度减去首部长度。

MSS尽可能大一些,使得IP层不要分片处理;MSS的默认值是536字节。

TCP可靠传输

工作原理

停止等待协议

每发送完一个数据就停止发送,等待对方确认,收到确认之后再进行下一次发送

  • 无差错情况

    A发送分组M1,发完就停止发送,等待B的确认;B收到M1后向A发送确认;A收到确认后,进行下一次分组的发送。

  • 出现差错

    B在接收分组M1时,检测出了差错就丢弃或者M1在传输过程中丢弃导致B没有收到。A中设有超时定时器,一段时间没有收到确认就重传,否则就撤销定时器,下一组发送。A在发送完一个分组后,必须暂时保留已发送分组的副本,只有收到确认后才清除;分组和确认分组都必须编号,明确是哪一个分组收到了确认。

  • 确认丢失和确认迟到

    B发送的对M1的确认丢失了。对A发送的重传分组丢弃,然后B继续发送确认分组;

    B发送的确认分组虽迟但到,A收到后丢弃,B收到的重传分组也丢弃(因为第一次还是收到了)。

信道利用率不高:A发送分组时间是Td,B发送确认分组时间是Ta,所以利用率U=Td/(Td+Ta

​ +RTT)

连续ARQ协议

发送窗口内的五个分组都可以连续发送,接收方一般使用累计确认的方式,对按序到达的最后一个分组发送确认,表示到目前这个分组为止的所有分组都已正确收到

可靠传输的实现

以字节为单位的滑动窗口

BYTEWindow

描述一个发送窗口的状态需要三个指针:

  • 小于P1表示已发送的并收到了确认,大于PE表示不允许发送。
  • P2-P1表示已发送但还没有收到确认。
  • P3-P2表示允许发送但尚未发送。
  • P3-P1表示B发送给A的窗口值大小,A根据这个大小设定窗口长度。

图中B收到了序号为32、33 的字节,但是没有按序到达,所以B发送确认报文时的确认号为按序收到的最高序号即31,不能是32 和33。

需要注意的问题:

  1. 同一时刻,A的发送窗口并不总是和B的接收窗口一样大,因为传送窗口值有一定的时间延后以及A根据网络拥塞情况适当减小发送窗口的值。
  2. 对于不按序到达的数据先临时存放在接收窗口中,等到所缺少的字节收到后,再按序交付上层的应用进程。
  3. 要求接收方有累计确认的功能,减小传输开销。

超时重传时间选择

加权平均往返时间RTTS(平滑的往返时间),a取1/8。

第一次收到RTT样本时,RTTS即为RTT样本值,以后的RTTS=(1-a)*(旧的RTTS)+a*(新的RTT)

RTT的偏差的加权平均值,β取1/4。

第一次收到RTT样本时,RTTD为RTT样本值的一半,以后的RTTd为

RTTD=(1-β)*(旧的RTTD)+β*|RTTs-新的RTT|

超时重传时间RTO

RTO=RTTS+4*RTTD

现在的问题是如何确定后来收到的确认报文段是重传报文的确认还是第一次的确认?

引出Karn算法:计算RTTS时,只要重传了,就不采用其RTT。

新的问题?—>如果时延增大了,那么不采用的话RTO不会更新,因此理论上每次重传都会收不到。

​ ---->采用如果重传了就把RTO增大一些

选择确认SACK

TCP数据报的首部格式里面有ACK选项。因此要使用选择确认的话,就应该在TCP数据报中加上这个选项,并且双方事先都商定好。 报告收到不连续字节块的边界,40字节,因此最多能表示4个字节块的边界信息。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R0x4eEsM-1649252569231)(/Users/medima/Desktop/SACK.png)]

注意不连续字节块的左右边界。

TCP的流量控制

流量控制即发送方速率不要太快,以便接收方来得及接收。

滑动窗口实现流量控制

接收方通过不断设置窗口值的大小来达到流量的控制。

考虑一种死锁情况 接收方发送了0️⃣窗口的报文,一段时间后,接收方又可以接受了,然后向发送方发送特定大小窗口的报文,但是传输过程中丢失了,A一直在等待,接收方也一直在等待数据的到来。

解决的方法是设一个持续计时器:收到零窗口后,就启动这个计时器,时间到了之后就发送一个零窗口探测报文段(仅1字节数据),接收方收到发送窗口值,发送方收到后如果窗口值是0就重新启动计时器;如果不是0,就可以继续发送数据了。

TCP的传输效率

Nagle算法:把发送的字节数据发送到TCP缓存,然后发送方发送第一个字节,后面到达的缓存起来,等待接收方发送确认报文,收到之后把缓存中的所有数据组装成一个报文段发送出去。

糊涂窗口综合症: 接收缓存满了,一次一个字节的发送和接收。可以让接收方等待一段时间之后,等待接收缓存有一半的空间时或者足够空间容纳一个最长的报文段时就发送确认报文。

TCP的拥塞控制

拥塞控制的一般原理

拥塞控制是防止过多的数据注入到网络中,使网络中的路由器或者链路不至于过载。

拥塞控制是一个全局性的过程。分组丢失只是拥塞发生的征兆,有时候拥塞控制设计的不合理也会导致拥塞。

trafficjams

拥塞控制方法

四种算法:慢开始、拥塞避免、快重传和快恢复。

慢开始和拥塞避免

**拥塞窗口:**发送方维持cwnd,让自己的发送窗口大小等于拥塞窗口。

控制拥塞窗口的原则:网络没有阻塞,窗口可以大一些,出现阻塞,就要减小。判断阻塞的依据是出现了超时。

慢开始算法:由小到大逐渐增大发送窗口(拥塞窗口)

规定初始拥塞窗口的大小为:

发送方最大报文长度SMSS,若SMSS > 2190字节,cwnd=2*SMSS;

​ 若SMSS > 1095 ,cwnd=3*SMSS ;

​ 若SMSS <=1095,cwnd=4*SMSS。

收到一个新的报文段后,cwnd每次的增加量 = min (N,SMSS)N是刚收到的确认收到字节数。

mansuanfa

实际运行时,只要收到一个确认报文段,cwnd就增加。

每经过一个传输轮次,cwnd 就加倍。

防止cwnd 过大引起网络拥塞 ,设置一个慢开始门限ssthresh。

  1. cwnd < ssthresh,使用慢开始算法
  2. cwnd > ssthresh,用拥塞避免算法
  3. cwnd = ssthresh,两个都可以用

拥塞避免算法:缓慢增大,每经过一个RTT就把发送方的拥塞窗口➕1。

manyongse

判断为网络拥塞之后,就重新慢开始。

个别报文段丢失,网络并没有发送阻塞,但是图中就会执行慢开始算法,导致效率变低。

快重传算法:要求接收方不要等待发送数据时才进行捎带确认,要立即发送,即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。

kuaichongchuan

拥塞控制流程

yongse

主动队列管理

全局同步:路由器的尾部丢弃策略(路由器队列满了之后对于以后到达的分组进行丢弃),导致许多TCP连接同一时间进入慢开始状态。

主动队列管理AQM:队列长度到达某个值时,就主动丢弃后到来的分组。

TCP的运输连接管理

连接建立(握手)

TCP jianli

  1. B 的 TCP 进程先创建传输控制块TCB(每一个连接中的重要信息),准备接收客户进程的连接请求,进入收听状态;

  2. A 的 TCP 进程也是先创建 TCB,向 B 发送请求报文段,首部中的同步为SYN=1,规定SYN报文段不能携带数据,但要消耗掉一个序号,TCP 客户进程进入同步已发送状态。

  3. B 收到请求连接报文段后,如同意连接就发送确认报文段, SYN = 1, ACK =1 ,确认号 ack = x + 1。这个报文段也不能携带数据,消耗掉一个序号,TCP服务进程进入同步收到状态。

    B 发送给 A 的报文段可以拆成两个报文段,先发送一个确认报文段(ACK = 1),后发送一个同步报文段(SYN = 1),变成了 四报文握手。

  4. A 收到 B的确认后,向 B 继续给出确认 ,ACK = 1,确认号ask = y + 1。ACK 报文段可以携带数据,如果不携带就不消耗序号,A进入已建立连接状态。

  5. B 收到 A 的确认后也进入连接已建立状态。

A最后发送一次确认的原因:防止已失效的连接请求报文段突然又传送到了B,因而发生错误。A 发出的第一个连接请求报文段没有丢失,而是滞留了,导致 A 重发了一次,但是在连接释放之后,B 又收到了这个请求,向A发送确认报文段和同步报文段,但是A并没有请求建立连接,所以A不予理睬,B等待一段时间没有确认报文段,就认为A 没有请求,放弃建立。

连接释放(挥手)

TCPshifang

  1. A 的应用进程向其 TCP 进程发送连接释放报文段,停止发送数据,主动关闭连接。
  2. 连接释放报文段 FIN 置 1,序号 seq= u(等于已传送过数据的最后一个字节的序号加1),这时进入终止等待 1 ,等待B的确认。
  3. B 收到连接释放报文段后就发出确认报文段,ACK =1,序号 seq = v(等于B 前面传送过的数据的最后一个字节的序号加1),然后B进入关闭等待状态。TCP 服务器进程通知高层进程,A 到 B 的方向的连接释放了,即半关闭状态,A没有数据要发送给 B 了,但 B 仍可以发送数据,A 仍要接收。
  4. A 收到 B 的确认报文段后,就进入终止等待 2,等待 B 发出的连接释放报文段。
  5. 若B没有数据要发送了,应用进程通知 TCP 释放连接,释放报文段 FIN =1,seq = w (半关闭状态B又发送了数据),ack = u+1(重复上次发送的确认号)。进入 最后确认状态。
  6. A 收到连接释放报文段后就必须发出确认报文段,ACK = 1,确认号 seq = u+1(前面发送过的连接释放报文段FIN 消耗掉一个序号),进入时间等待状态(现在TCP连接还未释放掉)。经过时间等待计时器设置的2 MSL (最长报文段寿命),A才进入CLOSED 状态。B 收到ACK 报文段后,也进入CLOSED 状态。

设置等待2 MSL 的原因:

  • 保证A发送的最后一个 ACK 确认报文段能够到达B。如果B收不到这个对他发送 的FIN+ACK报文段的确认的话,会超时重传,而 A在这个 2 MSL 时间内重新收到B的FIN+ACK 报文段,A又会重新发送一次 ACK 确认报文段,并重启时间等待计时器。如果不等待的话,B 无法正常进入CLOSED 状态。
  • 防止已失效的连接报文段出现在本连接中。

还设有保活计时器,用来防止客户机发送故障,服务器白白等待下去。

TCP的有限状态机

如下图:

TCP station

粗实线是客户进程的状态变迁;粗虚线是服务进程的状态变迁。

举报

相关推荐

0 条评论