计网笔记(6) 传输层

上课内容

  • 用于在不可靠网络中建立可靠链接
  • 网络层的复用,让多个应用层应用使用一个网络连接(通过端口及其相关机制区分)

服务原语

简单传输层服务的原语:
在这里插入图片描述
服务原语的使用:
在这里插入图片描述

  • TCP的socket原语(Berkeley Socket)
    在这里插入图片描述
  • 这里的accept相当于之前的listen,

一、运输层的端口

TCP/IP端口号为16位,但其指具有本地意义,表只应用层中各个进程与运输层交互时的层间接口。

服务器端口号

两大类:

  • 系统端口号:0-1023,他们被用于一些特殊用途,一般不改动
    在这里插入图片描述
  • 登记端口号:1024-49151 为没有系统端口号的应用程序使用。
客户端端口号

49152-65535 仅仅在酷虎进程运行时才动态选择

!扩展问题:一台机器所能容纳TCP连接的数量

  • 对于客户端机器,TCP的连接使用系统分配的端口(一般在linux为50000个左右),以及自身的ip地址决定,所以单ip地址下客户机能够建立的连接受sysctl -a | grep ip_local_port_range提供的动态端口范围限制。但docker等技术可以让客户机虚拟化多个网卡,这样就拥有了多个ip,此时最大连接数为每个容器ip地址下range大小的限制,当然也受总内存的限制
  • 对于服务端机器,TCP连接实际上是{自身ip,自身port,client ip,client port}四元组唯一决定,所以理论上其能维持的TCP连接无上限,但要维护一个连接最少需要3.3k内存,所以它维持连接数与内存有关

二、用户数据报协议UDP

特点:

  1. 无连接
  2. 尽最大努力交付
  3. 面向报文:发送方对应用程序交的报文,添加首部后就交给IP层,不合并也不拆分,保留其边界

适用场景

  • UDP没有拥塞控制,故对实时应用(电话,视频会议),可丢失但不允许大时延的场景有用
  • 支持一对一,一对多,多对一和多对多
  • 首部开销小(8byte)

首部字段结构

在这里插入图片描述
可以看到,首部字段时四个2字节字段:

  • 源端口
  • 目的端口
  • 长度:UDP用户数据报长度,最小是8(也即头部)
  • 检验和:检验包括头部和数据报(IP层只检验头部)是否有错,有则丢弃?

可以看到,同样的IP报,可以通过UDP实现基于端口的分用和复用

伪首部

UDP在计算checksum之前要增加12字节伪首部,如图
在这里插入图片描述
其中UDP长度与真正首部长度是相同的。伪首部只是临时添加的(不下传也不上交,信息是IP地址信息是应用层给的)。之后,将伪头部,真头部和数据包部分一起计算校验和。

UDP以16bit为1个checksum单位(因为校验和是16位),故当有奇数个数据字节时,会补上1个全0字节:
在这里插入图片描述

三、传输控制协议TCP的基础

特点

  1. TCP是面向连接的运输层协议
  2. 每一条连接只能点对点
  3. 提供可靠交付服务
  4. 提供全双工通信
  5. 面向字节流:它把应用层交下来的数据看作无结构的字节流

TCP拥有缓存,并且不关心应用程序发来报文的长度,它根据对方给出的window size当前网络拥塞程度决定一个报文段应该包含多少字节

TCP连接

TCP连接的端点是套接字(socket)。而端口号拼接到IP地址即构成了套接字
在这里插入图片描述
每一条TCP连接唯一地被通信两端的两个socket确定
在这里插入图片描述

四、TCP可靠传输的工作原理

停止等待协议

令A位发送方,B为接收方。停等协议指每发完一个分组就停止发送,等待对方的确认,收到确认后在发送下一个分组

无差错情况与有差错情况

在这里插入图片描述
最简单的情况是上图(a),接到了再发

如果B接受M1时出错,就扔掉分组,之后什么也不做(不通知A没收到),或者中间丢了,也是什么都不知道,相当于没通知A。一段时间后,A在超时计时器到期时没收到确认,就撤销超时计时器,并且重传M1分组,要实现这样的机制应当注意:

  • A发完分组后应当保存已发分组的副本直到其确认接受
  • 分组和确认分组需要编号
  • 显然,超时计时器重传时间要比数据在分组传输的平均时间长

确认丢失和确认迟到

对之前的出错情况,如果B的确认包传给A时丢了,A不知情,一段时间后这个分组M都会再被传过来,此时B收到了2次正确的M,它应该采取2个行动:

  1. 丢弃M不向上交付
  2. 向A发送重传确认分组

这是确认丢失的方法,情况如下:
在这里插入图片描述

而如果B发回去的确认包迟到了,在A重传之后才到,这是B会把第二次收到的M丢弃,并且发送重传确认分组。而A则收下迟到的分组但什么也不做。A需要等收到重发的M的确认分组之后再传之后的分组。这是确认迟到的方法
情况如下:
在这里插入图片描述

信道利用率

停等协议的优点是简单,但缺点是信道利用率太低
令:

  • T D T_D TD=发送分组时间
  • R T T RTT RTT=往返时间
  • 处理分组时间忽略不计
  • T A T_A TA=发送确认分组时间

则信道利用率为: U = T D T D + R T T + T A U=\frac{T_D}{T_D+RTT+T_A} U=TD+RTT+TATD
在这里插入图片描述

为了提高效率,需要使用流水线传输的连续ARQ协议

连续ARQ协议

使用滑动窗口,是TCP协议的精髓所在,后仔细讨论

五、TCP报文段首部格式

TCP传送的数据单元是报文段,分首部和数据段。
TCP首部前20个字节是固定的,后有>=0的4N个byte的option,首段固定部分各个字段的示意图和意义如下
在这里插入图片描述

字段名称字段长度字段含义
源端口和目标端口(src/des port)各2bytesrc和des的端口号
序号(Sequence Number)4byte其值= 真实序号% 2 32 2^{32} 232,序号的编址单位是字节,整个要穿的字节流的其实序号要在连接建立时设置,而首部的需要字段值是本报文段发送数据的第一个字节的序号
确认号(ACK number)4byte期望收到对方下一个报文段的第一个数据字节的序号,也即期望收到下一个TCP包的Seq number。它也意味着:若ACK=N,则N-1及之前的所有数据都已经正确收到。
首部长度/数据偏移(header length)4bit指出TCP报文段的数据起始处距离TCP报文段的头部起始处有多远。这其实指示了TCP首部长度(因为有option,所以它是必要的)。但要注意的是,数据便宜的单位是32bit(4字节,因为option也是按这个单位增加的),这也意味着option最长不超过40bit,但其实之后的保留位也使得option有增长空间
保留位已经减少到了4bit留作后用
CWR(Congestion Window Reduced)1bit让接收者直到发送者已经减缓发送,并且可以停止发送ECN-Echo
ECE(Explicit Congestion Notation)1bit向接收者发送ECN-Echo信号
URG(URGent pointer)1bit置位时使紧急指针有效,表示报文段中有紧急数据,应尽快传送(实际上是插到队列最前面),而不要按照排队顺序(例:Ctrl+C的中断应当立刻执行)
ACK1bit确认号,指示确认字段。TCP规定连接建立后所有报文段ACK都应当置1
PSH(PuSH,推送)1bit少用。发送方把PSH置1时,接收方收到后就尽快把信息交付给接受的进程,而不必等待缓存填满
RST(ReSeT,复位)1bit它置位时,表示TCP连接种出现严重差错,必须释放连接后重新连接;他也用来拒绝一个非法报文段或拒接连接
SYN(同步)1bit用于同步序号SYN=1,ACK=0时,表示这是一个连接请求报文段,如果同意,应让ACK和SYN置位。
FIN(终止)1bit置位时,表明报文端发送完毕,并要求释放运输连接
窗口长度(Window size)2byte指发送方对应的接收窗口,表示从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量。这个限制基于接收方有限的缓存空间。它是接收方让发送方设置其发送窗口的依据。
校验和(checksum)2byte包括首部和数据,和UDP一样要加上12byte伪头部,格式相同,但应改为TCP的协议号和对应数据
紧急指针(Urgent Pointer)2byte与URG通用,指出紧急数据的末尾位置(紧急数据后是普通数据),因此它也指示本报文段种紧急数据的字节数。
选项(options)0-40byte变长选项

六、TCP可靠传输的实现细节

以字节为单位的滑动窗口

基本示意图(A发,B接受):
在这里插入图片描述
如图,假定A收到了B的ACK报文段,其中window size是20(单位是byte),而确认号ack=31(表示B期望从31开始收)。这样A构造出了发送窗口。

超时重传时间选择

RTT = 收到确认时间-发出时间

使用加权的 R T T s RTT_s RTTs表示RTT,其中:
R T T s = ( 1 − α ) × o l d R T T S + α × n e w s a m R T T s RTT_s = (1-\alpha)\times oldRTT_S+\alpha \times newsamRTT_s RTTs=(1α)×oldRTTS+α×newsamRTTs,α多取0.125

超时重传时间RTO应该设置为: R T T S + 4 × R T T D RTT_S+4\times RTT_D RTTS+4×RTTD

其中RTTD是RTT偏差的加权平均值:
R T T D = ( 1 − β ) × o l d R T T D + β × ∣ R T T S − n e w s a m R T T S ∣ RTT_D = (1-\beta)\times oldRTT_D+\beta\times |RTT_S-newsamRTT_S| RTTD=(1β)×oldRTTD+β×RTTSnewsamRTTS,β去0.25

报文每重传1次,重传时间为2倍的重传时间,不再重传时恢复上述算法

选择确认(Selective ACK,SACK)

解决收到报文只有少量未按序号/序号缺失的情况。

如果要使用SACK,就要在TCP的首部中添加允许SACK的选项。使用后可以报告收到不连续的字节块的边界,而因为首部长度限制,其最多只能生命4个字节块,SACK应用较少。

七、TCP的流量控制

利用滑动窗口实现

发送方的发送窗口不能超过接收方的接收窗口(单位为字节)

TCP窗口的单位是字节

流量控制在ACK置位时才有意义

persistence timer

当B从无空间到有空间,发送有存储空间的ACK时,如果这个包丢了,A就会一直等B发送非0窗口,B也会一直等A发数据,就会产生死锁。
为了防止这种情况,TCP设置了持续计时器,它在一方收到0窗口时开始,如到期就发送一个1byte数据,接收窗口为0的探测报文段,对方会确认这个报文段,并给出接收窗口,如果还是0意味着确实没处理完,如果不是那么僵局就可以打破了。

传输效率

发送时机选择策略:

  1. 缓存达到MSS时发
  2. 发送方应用进程进行push操作
  3. 使用timer周期性发
    Nagle算法:
    应用进程要放到TCP缓存时,先发第一个byte,收到ACK后把缓存中所有数据打包。另外如果缓存数据达到发送窗口大小/达到MSS,立即发送一个报文段

糊涂窗口综合征及其解决办法:
接收方一次处理1byte,发送方一次发1byte,这会产生极大overhead,此时可以让发送方等待,使得接收缓存有一半空闲或能容纳一个MSS,再发出ACK通知窗口大小。并且发送方也要积累接收方缓存一半/MSS的报文段。

八、TCP的拥塞控制

一般原理

拥塞控制是防止过多数据进入网络导致过载,流量控制是点对点通信量的控制
在这里插入图片描述
横轴输入是单位时间内输入分组,纵轴是单位时间内输出分组。

拥塞控制方法

假定:数据单方传送,接收方缓存足够,单位是一个MSS

1. 慢开始和拥塞避免

发送方维持一个拥塞窗口cwnd(congestion window)的状态变量,其取决于网络拥塞程度且动态变化,不超过2~4个SMSS(发送方最大报文段)。发送方让自己的发送窗口小于等于拥塞窗口

1.1 慢开始算法

主机发数据是从小到大逐渐增大发送窗口(事实上是cwnd数值)

通常在开始时,先把cwnd设置为1,而每收到一个对新报文段确认后,把cwnd增加1
在这里插入图片描述

1.2 拥塞避免算法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.快重传&快回复

快重传:接收方应当及时发送重复确认,接收方收到3个重复确认后就重传重复确认指定的报文

快恢复:在这里插入图片描述

3. 主动队列管理AQM

网络层策略对TCP拥塞空值有影响,其中影响最大的就是router分组丢弃策略。如果按照最简单的FIFO原则,叫尾部丢弃。此时TCP的发送速率将急剧下降,可能导致全局同步(大量连接速率同快同慢)。
AQM的流行方法是随机早期丢弃:

  • 平均队列长度<minthreshold,enque
  • 平均队列长度>max threshold,丢弃
  • min<平均队列长度<max,以概率p丢弃新到达分组

九、TCP的运输连接管理

连接建立

在这里插入图片描述
一开始,B的TCP服务器进程先创建传输控制块TCB, 准备接受客户进程的连接请求。如有,即作出响应。

A的TCP客户进程也是首先创建传输控制模块TCB。 然后 , 在打算建立TCP连接时,向B发出连接请求报文段, 这时首部中的同步位SYN = 1, 同时选择一个初始序号 seq = x。TCP规定, SYN报文段(即 SYN=1的报文段)不能携带数据, 但要消耗掉一个序号。 这时, TCP客户进程进入SYN-SENT (同步已发送)状态。

B收到连接请求报文段后, 如同意建立连接, 则向A发送确认。 在确认报文段中应把SYN位和ACK位都置1, 确认号是ack = x + 1, 同时也为自己选择一个初始序号seq = y。 请注意, 这个报文段也不能携带数据, 但同样要消耗掉一个序号。 这时 TCP服务器进程进入SYN-RCVD (同步收到)状态。

TCP客户进程收到B的确认后, 还要向B给出确认。 确认报文段的ACK置1, 确认号ack = y+ 1, 而自己的序号seq = x+1。TCP的标准规定, ACK报文段可以携带数据。 但如 果不携带数据则不消耗序号, 在这种情况下, 下一个数据报文段的序号仍是seq = x+1。这 时, TCP连接已经建立, A进入ESTABLISHED (已建立连接)状态。

当B收到A的确认后, 也进入ESTABLISHED状态。

issue

  • A为什么要最后一次确认?
    防止已失效的连接请求报文突然传送到了B。如果一个连接请求报文在长时间阻塞后(指A不在和B建立连接),B返回的确认报文A自然不会理睬,但B却认为连接已建立,耗费资源等待数据(或是自己空发数据)。

连接释放

在这里插入图片描述
通信双方都可释放连接。现在A和B都处于ESTABLI SHED状态。A的应用进程先向其TCP发出连接释放报文段, 并停止再发送数据, 主动关闭TCP连接。 A把连接释放报文段首部的终止控制位FIN置1, 其序号seq = u, 它等于前面已传送过的数据的最后一个字节序号+1.此时A进入FIN-WAIT-1状态,等待B确认,即便不携带数据也消耗一个信号。

B收到连接释放报文段后即发出确认, 确认号是ack = u + 1, 而这个报文段自己的序号是v,等于B之前传送的最后一个byte序号+1,之后B进入CLOSE-WAIT(关闭等待)状态。TCP服务器进程这时应通知高层应用进程, 因而从A到B这个方向的连接 释放了, 这时的 TCP连接处于半关闭(half-close)状态, 即A 已经没有数据要发
送了, 但B若发送数据, A仍要接收。 也就是说, 从B到A这个方向的连接并未关闭, 这个状态可能会持续一段时间。

A收到来自B的确认后, 就进入FIN-WAIT-2(终止等待2)状态, 等待B发出的连接释放报文段。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值