运输层
运输层服务
运输层协议:为运行在不同主机上的应用进程提供逻辑通信功能(主机直接相连)。即端到端传输。
进程之间使用逻辑通信功能彼此发送报文,无需考虑具体物理链路。
运输层协议运行在端系统,不在路由器中。
-
发送方:将应用进程的报文划分成若干段,封装后传给网络层。
-
接收方:将网络层上传的报文段,重新装配为报文,传向应用层。
路由器只根据网络层字段而动作。
运输层和网络层的关系
运输层位于网络层上。
-
网络层提供主机之间的逻辑通信。
-
运输层为运行在不同主机上的进程之间提供逻辑通信;
依赖、强化网络层服务
运输层概述
UDP(用户数据报协议):为应用程序提供不可靠,无连接的服务。
TCP(传输控制协议):为应用程序提供可靠的,面向连接的服务。
报文段(segment):运输层分组。
数据报(datagram):网络层分组。
网络层概述
IP(网际协议):为主机之间提供逻辑通信。
-
IP服务模型:尽力交付服务。
尽最大的努力在通信的主机之间交付报文段,但不保证按序交付或数据的完整性。属于不可靠服务。
-
IP地址:主机的网络层地址。每台主机有一个。
UDP和TCP的服务模型
将两个端系统间IP的交付服务扩展为运行在两个端系统上的进程之间的交付服务。
即主机间交付扩展到进程间的交付。运输层的多路复用和分解
- 可提供完整性检查。
- UDP是不可靠服务。
- TCP提供可靠数据传输及拥塞控制。
复用与分解
将网络层所提供的主机到主机交付服务扩展到在主机上运行的应用程序到应用程序的交付服务。
- 主机上可以有多个应用进程运行。
- 当运输层从底层网络接收数据时,应能正确地定向到相应的一个进程(套接字)
![image-20210105115442878](https://gitee.com/firefrom/pics/raw/master/Net/image-20210105115442878.png)
套接字
从网络向进程传递数据,或从进程向网络传递数据的门户。
- 运输层和应用进程通过套接字来传递数据。
- 主机上的套接字可以有多个,每个套接字都有惟一的标识符(格式取决于UDP或TCP)。
多路复用与分解过程
多路复用(发送主机): 从不同套接字收集数据块,并*为每个数据块封装上首部信息,生成报文段,*传递到网络层。
多路分解(接收主机):*将报文段中的数据交付到正确的套接字。*即接收方运输层从报文段的多个字段中,识别出套接字,并将报文段定向到该套接字。
过程事例
- 主机1:运输层收集套接字输出的数据,形成运输层报文段,将其传递给下面的网络层(多路复用)
- 主机2:运输层将从其网络层收到的报文段多路分解后通过相应的套接字交给其上的P1进程。
目的主机分解过程
- 当报文段到达主机时,运输层检查报文段中的目的端口号,将其定向到相应的套接字。
- 报文段中的数据通过套接字进入其所连接的进程。
报文段格式
端口号:主机上的每个套接字分配一个16位端口号。(0-65535)
- 0-1023 为常用端口号
- 开发新应用时需选择一个端口号
无连接的多路复用与分解
UDP的多路复用与分解
创建UDP套接字的方法
-
自动为该套接字分配一个端口号。
DatagramSocket mySocke = new DatagramSocket()
从1024~65535的号码中分配一个主机尚未使用的UDP端口号。 -
直接为套接字指定一个特定的端口号。
DatagramSocket mySocke = new DatagramSocket (19157)
客户机端 | 服务器端 |
---|---|
自动分配端口号 | 分配一个特定的端口号。 |
若使用“周知协议”,必须分配一个相应的周知端口号。 |
发送方 多路复用 | 接收方 多路分解 |
---|---|
运输层创建一个报文段(数据、源端口号、目的端口号) | UDP报文段到达接收方 |
传递到网络层; | 通过报文段中的目的端口号,将报文段定向(多路分解)到相应的套接字 |
网络层将该报文段封装到IP报文中,并尽力交付给接收主机 | 并交给相应进程。 |
UDP套接字
UDP套接字组成(标识目的套接字): 二元组(目的IP地址,目的端口号)
- 具有不同源套接字,但具有相同目的套接字的UDP报文段,接收段可通过相同套接字定向到相同的目的进程(多对一)
- 源端口号的作用:目的方回发报文段中的返回地址
面向连接的多路复用与分解
TCP的多路复用与分解
TCP套接字
标识目的的套接字:四元组 (源IP地址,源端口号,目的IP地址,目的端口号)
- 目的主机使用全部四个值来将收到的TCP报文段定向(分解)到对应的套接字
- 两个具有不同源套接字的TCP报文段,将被定向到不同的两个套接字
TCP的连接与分解
- 服务器应用程序在某个端口上等待TCP客户机连接建立请求。如
ServerSocket welcomeSocke = new serverSocket(6789) - TCP客户机在相应端口上产生一个连接建立请求报文段。
Socket clientSocke = new Socket (“serverHostName”,6789) - 当服务器收到客户机的连接请求后,通知服务器进程,并创建一个连接套接字。如,
Socket connectionSocket = WelcomeSocket.accept() - 连接套接字通过4个值来标识。
- TCP连接完成后,客户机和服务器可相互发送数据。
- 当一个TCP报文段到达主机时,根据4个字段值的来定向(多路分解)到相应的套接字。
说明 | |
---|---|
一个web服务器可以同时与多个客户机连接,并产生多个进程。 | |
每个进程都有自己的连接套接字,通过这些套接字可以收到HTTP请求和发送HTTP响应。 | |
性能Web服务器通常只使用一个进程,可以为每个新连接创建一个新线程(一个轻量级的子进程)。 |
实例
主机C向服务器B发起两个HTTP会话;
主机A向服务器A发起一个HTTP会话。
多线程Web服务器
无连接服务:UDP
基本概念
特点 | 尽最大努力交付 | 丢包 对应用程序交付失序 |
---|---|---|
无连接 | 在UDP发送方和接收方之间无握手 每个UDP段单独处理 | |
使用原因 | 无连接创建 | 减少时延 |
简单 | 无连接 | |
段首部小 | 传销开销小 | |
无拥塞控制 | UDP能尽可能快地传输 | |
应用 | 流式多媒体 | DNS(域名系统) |
SNMP | ||
经UDP的可靠传输 | 在应用层增加可靠性,实现特定的差错恢复! |
UDP报文段结构
UDP检查和
用于检查所传输的报文段中的比特差错 (如比特翻转)。
发送方: | 接收方: |
---|---|
数据的每两个字节当作一个16位的整数,可分成若干整数; | 对接收到的信息 (包括检查和)求和 全“1”:数据无错; 其中有“0”:数据出错 |
将所有16 位的整数求和 | 对接收到的信息 (不包括检查和)求和 核对计算的检查和并取反是否等于检查和字段的值 |
对得到的和逐位取反,作为检查和,放在报文段首部,一起发送。 |
实例
作加法时,最高位的进位要回加到结果中。
![image-20210105152406869](https://gitee.com/firefrom/pics/raw/master/Net/image-20210105152406869.png)
可靠数据传输原理
可靠数据传输的问题在运输层、链路层及应用层都会出现。
- 数据通过一条可靠的信道传输
- 即传输的数据不出错,丢失,并按照发送的顺序传送
![image-20210105153159661](https://gitee.com/firefrom/pics/raw/master/Net/image-20210105153159661.png)
可靠传输实现
设计可靠数据传输协议
低层信道不太可靠,通过使用可靠数据传输协议来保证可靠的数据传输。
分别设计可靠数据传输协议的发送方和接收方。
基本实现
发送方 | 接收方 |
---|---|
通过*rdt_send()*函数调用可靠数据传输协议的发送方(rdt表示“可靠数据传输”协议)。 | 当一个分组从信道抵达时,调用*rdt_rcv()*接收; |
*udt_send()*用来发送分组给对方(udt表示“不可靠数据传输”) | 调用*deliver_data()*将数据交付给上层。 |
- 只考虑单向数据传输,数据传输从发送方到接收方
- 发送方和接收方可以来回交换控制分组(控制信息双向流动)
- 使用有限状态机(FSM)来定义发送方和接收方
有限状态机概述
- 箭头:表示协议从一个状态变迁到另一个状态
- 横线上方:表示引起变迁的事件
- 横线下方:表示事件发生时所采取的动作
- ∧:表示没有事件或未采取动作
- 虚线:表示FSM的初始状态
构造可靠的的数据传输协议
rdt1.0 完全可靠信号的上的可靠数据传输
RDT1.0
条件假设
- 底层信道完全可靠:数据传送 不出错不丢失
- 收发双方速率匹配:接收方接受数据的速率和发送方发送数据一样快
- 所有分组都是从发送方流向接收方
- 接收方无需反馈信息,因为无差错发生
rdt1.0的FSM
接受发送方FSM相互独立
顺序 | 发送方 | 接收方 |
---|---|---|
事件 | 从上层接受数据rdt_send(data) | 从底层信道接收一个分组rdt_rcv(packet) |
活动 | 封装成分组make_pkt(data) | 解封取出数据extract(packet,data) |
将分组发送到信道中udt_send(packet) | 据传给上层deliver_data(data) |
rdt 2.X具有比特差错信道上的可靠的数据传输
RDT2.0 停止等待协议:发送方发完一个分组后停止,等待对方回答
条件假设
- 信道不完全可靠,可能产生比特差错,但不丢包
- 所有分组按序发送并被接收(有些bit可能出错)
肯定确认,否定确认
类比例:
- 打电话传递一条长信息
- 收听者:
听清每句话后说“OK”(肯定确认);
听到不清楚的话,要求对方重复说“请重复一遍”(否定确认)。
肯定确认:告诉发送方内容被正确接收。
否定确认:告诉发送方内容出错需要重传
基于重传机制的可靠数据传输协议称为自动重传请求协议ARQ(Automatic Repeat request)
ARQ协议处理比特差错机制
差错检测
使接收方检测出是否出现比特差错。
- 如采用差错检测和纠错技术,使接收方能够进行差错检测并纠正。
- 需要给分组附加额外的比特一起发送。如rdt2.0协议,分组增加检验和checksum字段。
接收方反馈
使发送方知道发送的分组是否被正确接收。
- 通过接收方回送肯定确认(ACK)和否定确认(NAK) 分组完成。
- 如rdt2.0协议,接收方将向发送方回送*ACK(“1”比特)或NAK(“0”比特)*分组。
重传
接收方收到有差错的分组时,通知发送方重传该分组。
rdt2.0特点
- 可以解决数据分组出错问题。
- 若返回ACK或NAK分组受损,发送方无法知道接收方是否正确接收了上一块数据。
rdt2.0的FSM
停等(stop-and-wait)协议:发送方发完一个分组后停止,等待对方回答。
基本模型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BKRkbFk6-1610437010294)(D:\StudyData\Notes[其他]计算机通用知识\CNpics\image-20210105160439748.png)]
顺序 | 发送方 | 接收方 | |||
---|---|---|---|---|---|
等待上层调用 | 等待上层数据 | 从底层接收一个分组 检查校验和 | |||
事件 | 层数据传来rdt_send(data) | 分组出错 | 事件 | rdt_rcv(rcvpkt) && corrupt(rcvpkt) | |
活动 | 计算校验和,封装成分组make_pkt(data,checksum) | 活动 | 丢弃分组 | ||
发送分组udt_send(sndpkt) | 返回NAK 分组udt_send(NAK) | ||||
收到ACK分组 | 事件 | rdt_rcv(rcvpkt) && is ACK(rcvpkt) | 分组无错 | 事件 | 收到分组且无错误rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) |
活动 | 返回初始状态 | 活动 | 从分组中取出数据extract(rcvpkt,data) | ||
收到NAK分组 | 事件 | rdt_rcv(rcvpkt) && is NAK(rcvpkt) | 将数据传给上层deliver_data(data) | ||
活动 | 重传上次发送的分组udt_send(sndpkt) | 返回ACK 分组udt_send(ACK) | |||
等待ACK或NAK |
- 当发送方在等待ACK或NAK状态时,不能从上层得到数据,直到收到ACK离开该状态。
- 发送方在收到ACK分组之前,不会发送任何新数据,直到收到ACK分组为止。
无错误场景
![image-20210105180833963](https://gitee.com/firefrom/pics/raw/master/Net/image-20210105180833963.png)
有错误场景
![image-20210105180851519](https://gitee.com/firefrom/pics/raw/master/Net/image-20210105180851519.png)
处理受损ACK和NAK的可能方法
收发双方互不理解对方回答的含义使对话不能正常进行。
-
增加足够的检验和比特:
使接收方不仅可以检测差错,还可进行恢复。适用于会产生差错但不丢失分组的信道。
-
当发送方收到含糊不清的ACK或NAK分组时:简单地重发当前数据分组。
产生冗余分组(duplicate packets):同一个分组收到两次。接收方无法知道收到的是新的分组还是重传的分组。
冗余分组解决方法
给分组添加一个序号字段。
-
发送方:给发送的数据分组编号,并将其序号放入“序号字段”。
每发送一个新的分组*“序号加1”。*
-
接收方:通过检查序号,确定收到的分组是不是重复传送。
按序号接收,若本次接收到的分组序号与前一次收到的分组的序号相同,即为重复分组,将该重复分组丢弃。
序号位数选择
停等协议:只需用一个比特,即“0”和“1”两种不同的序号。
序号通过模2运算向前移动,可以区分前后相邻的两帧。0、1、0、1、……
说明
-
ACK和NAK分组不需要指明要确认的序号。因为假设信道不丢失分组。
不丢失必然有序,故此ack,nak天然带序号
-
发送方知道所接收的ACK和NAK分组是对最近发送分组的响应。
rdt2.1
可以处理重复分组
判断分组是否重复方法:当前所处状态提供了期望收到分组的的序列号
相较rdt2.0多了序列号
- 指出正发送或准备接收的分组的序号。
- 发送或期望接收0号分组的状态中的动作与发送或期望接收1号分组的状态中的动作相似,只是序号处理方法不同。
- 使用从接收方到发送方的肯定和否定确认。
发送方
接收方
发送方 | 接收方 |
---|---|
上层取数;发0# 分组 | 收到受损的分组:丢弃,并回发一个否定确认(NAK ) |
收到错误分组或NAK;发0# 分组 | 收到乱序的分组:是重复分组,丢弃,并回发一个肯定确认( ACK ) 。 |
收到ACK; | |
上层取数发1# 分组 | |
收到错误分组或NAK;重发1# | |
收到ACK |
- 对收到0或1且内容正确,必发ack,因为收到正确内容则可以继续接收下一个数据
rdt2.1 vs rdt2.0 | |
---|---|
发送方 | 接收方 |
每个分组增加了序列号 | 需判断分组是否重复 当前所处转股管态提供了期望收到分组的序列号 |
两个序列号(0,1)够用,采用平等协议,收到的内容正确的皆可用于数据 | 接收方无法知道ACK/NAK是否被发送方正确收到 |
状态数量翻倍;状态必须记住当前的分组序列号 |
rdt2.2
无NAK消息协议;给ACK标记序列号
- 接收方通过ACK告知最后一个被正确接收的分组
- 在ACK消息中显示地加入被确认分组的序列号
- 发送方收到重复ACK之后,采取与收到NAK消息相同的动作重传当前分组
发送方
![image-20210105201934426](https://gitee.com/firefrom/pics/raw/master/Net/image-20210105201934426.png)
接收方
![image-20210105201954723](https://gitee.com/firefrom/pics/raw/master/Net/image-20210105201954723.png)
rdt3.0 具有比特差错的丢包信道上的可靠的数据传输
保证可靠数据传输协议的要点:检验和、序号、定时器、重传、肯定和否定确认。
假设条件
- 会出现比特差错
- 会出现丢包
- 发送的的数据分组丢失
- 或接收方回发的AKC丢失
发送方发现丢包处理方法
发送方等待合理时间
-
若未收到ACK,重传
-
若分组或ACK只是延迟而非丢失
- 重传产生重复,序列号机制能够处理
- 接收方需在ACK中显式告知所确认的分组
-
需要定时器
设置一个“递减(倒)计数定时器”,给定时间过期后,中断发送方。
要求发送方:
- 每发送一个分组(包括第一次和重发的分组),启动一个定时器;
- 响应定时器中断:采取适当的动作;
- 终止定时器。
rdt3.0的FAM
发送方
![image-20210105203714861](https://gitee.com/firefrom/pics/raw/master/Net/image-20210105203714861.png)
接收方
rdt3.0接工作场景
无差错与分组丢失
![image-20210105203856214](https://gitee.com/firefrom/pics/raw/master/Net/image-20210105203856214.png)
ACK丢失与过早超时
![image-20210105203921011](https://gitee.com/firefrom/pics/raw/master/Net/image-20210105203921011.png)
停止-等待协议流程
基本概念
-
N(S):发送序号变量,当前传送分组的编号,发送新分组时,N (S)+1;
-
V®:接收序号变量,当前准备(希望)接收的分组序号,每收到一个新分组时,V®+1;
-
判断重复分组(接收方):
N(S) = V®,收到的是新数据分组;
N(S) != V®,收到的是重复分组。
发送方和接收方流程
发送方
![image-20210106112842977](https://gitee.com/firefrom/pics/raw/master/Net/image-20210106112842977.png)
接收方
![image-20210106113236456](https://gitee.com/firefrom/pics/raw/master/Net/image-20210106113236456.png)
停等协议效率
能够正常工作,但效率不高。
发送方(信道)利用率Usender = 发送方将比特发送到信道的时间/发送时间 即(传输时延L/R/发送方从发送分组开始,到收到对方ACK分组,所需的时间。)
- 两个端系统之间的光速往返传播时延RTT约 30ms
- 信道传输速率 R=1Gb/s(109bit/s)
- 分组长 L = 1000字节
![image-20210106114910238](https://gitee.com/firefrom/pics/raw/master/Net/image-20210106114910238.png)
![image-20210106114921903](https://gitee.com/firefrom/pics/raw/master/Net/image-20210106114921903.png)
- 发送方只有0.027%的时间忙。
- 发送方在30.008ms内只能发送l000byte,有效的吞吐量仅为267kbit/s(l000X8/(30.008X10-3),即使有1Gbit/s的链路可用)
流水线技术改进效率
允许发送方连续发送多个分组而无需等待确认,称为流水线技术(众多分组可看成是填充到一条流水线中)。
N为连续发送分组个数
应用实例
技术要点
- 增加序号范围:由于可连续发送多个分组,每个分组有唯一序号,可能有多个在传输中的未确认报文。
- 需要缓存多个分组:
发送方至少能缓冲已发送但没有确认的分组;
接收方缓存已正确接收的分组。 - 序号范围和对缓存的要求:取决于数据传输协议处理丢失、差错及过度延时分组的方式。
滑动窗口协议(Silding-window protocol)
窗口:
- 允许使用的序列号范围
- 窗口尺寸为N:最多有N个等待确认的消息
滑动窗口:
- 随着协议的运行,窗口在序列号空间内向前滑动
主要类型:GBN,SR
GBN协议
回退N步 (Go-Back-N, GBN协议)
GBN协议综合可靠数据传输的全部技术:使用序号、累积确认、检验和以及超时/重传操作等
GBN缺点:可能需要很多的重传
基本思想
发送方:连续发送多个数据分组,停止等待
- 收到确认ACK,继续发送后面分组;
- 超时,未收到应答,从出错分组开始重发
接收方:按序号接收数据分组
- 正确:接收处理,发确认ACK;
- 出错:将出错分组及后面分组均丢弃,不发任何应答。
注意事项
- 连续发送的分组个数不能太多:
增加序号字段位数;
出错时,要重传很多数据分组,影响效率。 - 连发个数受流水线中未确认的分组数限制,不能超过最大允许数N。
通过设置发送窗口和接收窗口来分别控制连续发送和接收的分组个数。
发送方
控制发送方连续发送的个数
实际是允许连续发送的序号表,只有落在发送窗口所包含序号之内的,才能不等待应答发送。
-
分组头部包含k-bit序列号
-
窗口尺寸为N,最多允许N个分组为确认
-
ACK(n):确认序列号n(包含n)的分组均已被正确接收 累计确认
可能收到重复ACK
-
为空中的分组设置计时器(timer)
超时Timeout(n)事件:重传序列号大于等于n,还未收到ACK的所有分组
![image-20210106122545380](https://gitee.com/firefrom/pics/raw/master/Net/image-20210106122545380.png)
序号范围分割成4部分:
- [0,base-1]:已经发送并确认过的分组。
- [base,nextseqnum-1]:已经发送但未被确认分组
- [nextseqnum,base+N-1]:用于将立即发送的分组
- [base+N, ]不能使用,直到当前流水线中未被确认的分组得到确认(序号为base的分组)。
发送窗口大小WT
- WT = N,即序号范围[base,base+N-1],包括已发送未被确认的分组、以及准备发送的分组。
- 随着协议的运行,发送的分组陆续被确认,发送窗口在序号空间内向前滑动。
- 若分组序号字段的位数是k,则序号范围是[0,2k-1]
发送方扩展FSM
响应的事件:
-
上层的调用:上层调用rdt_send()检查发送窗口是否已满(是否有N个已发送、但未被确认的分组)
窗口未满:创建一个分组并将其发送,更新变量
窗口已满:将数据返回给上层,以后再试。 -
收到ACK: 对序号为 n的分组的确认使用累积确认,即表明接收方已正确接收到序号为n及以前的所有分组(从接收方来说,如果n分组以前有一个分组没有正确收到,接收方是不会发出n分组的确认的;所以发送方只要收到n的确认即说明n及以前分组接收方都正确收到了,但是发送方不一定能收到所有n及以前分组的确认,因为有些确认分组可能丢掉了)。
-
超时:设置定时器处理*“数据或确认分组丢失”*情况
只使用一个定时器,作为最早的已发送但未被确认的分组的定时(每次窗口滑动后,还有已发
未确认分组时,定时器都重新开始对窗口中基序号分组进行倒计时,即基序号变化且还有已发未确认分组时将重启定时器)。
产生超时:发送方重发所有已发未确认分组。
收到一个ACK: 仍有已发送但未被确认的分组,重新启动定时器。
没有未确认报文,终止定时器。
![image-20210106123316471](https://gitee.com/firefrom/pics/raw/master/Net/image-20210106123316471.png)
接收方
按序接收。接收方WR=1。
- 正确按顺序接收到序号为n 的分组:将分组中的数据交付到上层,并回发一个 ACK;
- 分组一次性交付给上层:分组k 被交付, k之前均已交付。
- 其他情况的分组:丢弃该分组,并为最近按序接收的分组重发ACK。
- 丢弃所有失序分组:控制简单,接收方不需要缓存任何失序分组。
接收方扩展FSM
ACK机制: 发送拥有最高序列号的、已被正确接收的分组的ACK
- 可能产生重复ACK
- 只需要记住唯一的expectedseqnum
乱序到达的分组:
- 直接丢弃->接收方没有缓存
- 重新确认序列号最大的、按序到达的分组
![image-20210106125356641](https://gitee.com/firefrom/pics/raw/master/Net/image-20210106125356641.png)
- 接收方维护下一个按序接收的分组的序号,该值保存expectedseqnum变量中。
窗口为4的GBN协议的运行
-
发送方:连续发送4个分组后等待,直到一个或多个分组被确认;
每接收到一个连续的ACK时,该窗口便向前滑动。
-
接收方:收到一个连续的正确的分组,窗口向前滑动。
![image-20210106125921750](https://gitee.com/firefrom/pics/raw/master/Net/image-20210106125921750.png)
SR协议
选择性重传 (Selective Repeat, SR协议)
发送方只重传出错(丢失或受损)的分组。
SR协议的发送方和接收方窗口不总一致
基本概念
GBN需要重传很多分组
发送方:连发多个数据分组,停止等待
- 收到确认ACK,继续发送后面分组;
- 超时,未收到应答,只重发出错分组。
接收方:不按序号接收数据分组
- 正确:接收、按顺序交付,发确认ACK;
- 出错:丢弃该分组,以后正确分组放入缓存,当出错分组正确收到后,按顺序一起交付。
不按序接收。接收窗口大小 > 1,即只要序号落在接收窗口内的正确分组都可接收。
某时刻发送方/接收方窗口
![image-20210106151703689](https://gitee.com/firefrom/pics/raw/master/Net/image-20210106151703689.png)
发送方的事件与动作
事件 | 动作 |
---|---|
从上层收到数据:当从上层接收到数据后,发送方检查下一个可用于该分组的序号。 | 若序号在发送方窗口内,则将数据打包并发送 |
否则:与GBN一样,将数据缓存,或将其返回给上层,以后再传。 | |
超时:每个分组有自己的定时器,超时后只能发送一个分组。 | |
收到ACK:将被确认的分组标记为*已接收(*若该分组序号在窗口内)。 | 如果该分组的序号等于发送基序号send_base,则窗口基序号向前移动到具最小序号的未确认分组处。 |
窗口移动后,仍有序号落在窗口内的未发送分组,继续发送。 |
接收方的事件与动作
接收方接收正确分组不管其是否有序。
事件 | 动作 |
---|---|
失序分组: | 先被缓存,直到所有丢失分组(序号更小的分组)被收到为止,才可将一批分组按序交付给上层。 |
序号在接收窗口内的分组被正确接收:收到的分组落在*[rcv_base,rcv_base+N-1]内,接收并回发一个ACK。* | 该分组以前没收到过:被缓存; |
该分组的序号等于接收基序号:则该分组及已缓存的序号连续的分组交付(起始于基序号)给上层。接收窗口按交付的分组数量向前移动。 | |
收到序号在接收基序号以前的分组: | 该分组是接收方以前已确认过的分组。*生成一个ACK, 并回发给发送方。*如果接收方不确认,发送方窗口不能向前滑动。 |
其他情况: | 忽略该分组。 |
SR协议示例
![image-20210106154122594](https://gitee.com/firefrom/pics/raw/master/Net/image-20210106154122594.png)
窗口最大尺寸
若序号位数k位,SR协议,发送窗口和接收窗口尺寸最大是2k-1,不是2k-1。即序号空间一半。
避免发生接收序号重叠,出现重复分组
反例说明:
设序号2位,则序号空间为0#~3#,发送窗口和接收窗口尺寸最大是2,不是3。
三种协议比较
![image-20210106155521728](https://gitee.com/firefrom/pics/raw/master/Net/image-20210106155521728.png)
可靠传输机制及用途总结
机制
-
校验和:检测分组传输中的比特错误。
-
定时器:用于检测分组超时及重传分组
分组或ACK丢失;
一个分组被延时但未丢失(过早超时),或ACK丢失,接收方可能会收到重复分组。 -
序号:发送的数据分组按顺序编号。
接收方可检测分组丢失(序号间的空隙)或重复(相同序号的分组)。 -
**ACK确认:**接收方用其告诉发送方某个分组或一组分组已被正确地接收。
确认报文包含被确认的分组或多个分组的序号。可以是逐个的或累计。 -
**NAK否认:**接收方告诉发送方某个分组尚未正确地接收。包含未被正确接收的分组的序号。
-
*窗口、流水线:*发送方可以连续发送序号落在发送窗口序号范围内的分组,可以不用逐个确认。
问题
-
即使发送方或接收方的窗口中都没有包含x,但可能会出现一个具有序号或确认号x的分组的旧拷贝。
-
为确保序号不被重新使用,需要*发送方“确信”*任何先前发送的序号为x的分组都不再在网络中为止。
-
*规定分组最长的寿命:*分组在网络中“生存”的时间不会超过某个固定的最长时间。
如在TCP中假定为大约3分钟。
面向连接服务:TCP
采用:差错检测、重传、累积确认、定时、序号和确认序号。
TCP概述
特点
特点 | 描述 |
---|---|
点对点 | 一个发送方,一个接收方 |
可靠的、按序的字节流 | |
流水线机制 | TCP拥塞控制和流量控制机制设置窗口尺寸 |
发送方/接收方缓存 | ![]() |
全双工(full-duplex) | 同一连接中能够传输双向数据流 |
面向连接 | 数据交换前,发送方与接收方进行握手(交换控制信息)。 |
连接状态与端系统有关,不为路由器所知。 | |
多播 | 一个发送方同时传给多个接收方。 |
流量控制机制 | 发送方发送速率不能超过接收方能力。 |
拥塞控制 | 网络拥塞时遏制发送方速率。 |
通信过程
- 建立TCP连接:三次握手。
- 进程通信:通过套接字发送及接收。
封装成报文段传输。
报文段结构
TCP序列号与ACK
序列号
-
序列号指的是segment中第一个字节的编号,而非segment的编号
-
建立TCP连接时,双方只能随机选择序列号
ACKs
-
希望收到的下一个字节的序列号
-
累计确认:该序列号之前的所有字节均已被正确接收到
由TCP实现者做出决策如何处理乱序到达的Segment
TCP的可靠数据传输
技术 | 细节 |
---|---|
TCP在IP层提供的不可靠服务基础上实现可靠数据传输服务 | |
流水线机制 | |
累积确认 | |
TCP使用单一重传定时器 | |
触发重传的事件 | 超时 |
收到重复ACK | |
渐进式 | 暂不考虑重复ACK |
暂不考虑流量控制 | |
暂不考虑拥塞控制 |
TCP连接管理
建立连接 3次握手
3次握手机制
Client:是连接发起者
Server:等待客户连接要求
使用三次握手原因:为了防止服务器端开启一些无用的连接增加服务器开销以及防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
步骤 | 行为 | 细节 |
---|---|---|
Step 1: | client host sends TCP SYN segment to server | specifies initial seq # |
SYN标志位置1,表示要建立连接;并选择初始序列号 | no data | |
Step 2: | server host receives SYN, replies with SYNACK segment | server allocates buffers |
我也要和你建立连接,发送SYNACK报文段 | specifies server initial seq. # | |
Step 3: | client receives SYNACK, replies with ACK segment, which may | |
答复一个ACK报文段,SYN不再置1;我收到你同意我建立连接的报文段 |
![image-20210106200905742](https://gitee.com/firefrom/pics/raw/master/Net/image-20210106200905742.png)
关闭连接 4次挥手
四次挥手
Client 和 server都可为发起者
一般为Client
步骤 | 行为 | 细节 |
---|---|---|
Step1 | 首先客户端想要释放连接,向服务器端发送一段TCP报文 | 标记位为FIN,表示“请求释放连接“; 序号为Seq=U; 随后客户端进入FIN-WAIT-1阶段,即半关闭阶段。并且停止在客户端到服务器端方向上发送数据,但是客户端仍然能接收从服务器端传输过来的数据 |
Step2 | 服务器端接收到从客户端发出的TCP报文之后,确认了客户端想要释放连接,随后服务器端结束ESTABLISHED阶段,进入CLOSE-WAIT阶段(半关闭状态)并返回一段TCP报文 | 标记位为ACK,表示“接收到客户端发送的释放连接的请求”; 序号为Seq=V; 确认号为Ack=U+1,表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值; 随后服务器端开始准备释放服务器端到客户端方向上的连接。 |
Step3 | 服务器端自从发出ACK确认报文之后,经过CLOSED-WAIT阶段,做好了释放服务器端到客户端方向上的连接准备,再次向客户端发出一段TCP ACK报文, | 标记位为FIN,ACK,表示“已经准备好释放连接了” 序号为Seq=W 确认号为Ack=U+1;表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值。 |
Step4 | 客户端收到从服务器端发出的TCP报文,确认了服务器端已做好释放连接的准备,结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,并向服务器端发送一段报文 | 标记位为ACK,表示“接收到服务器准备好释放连接的信号”。 序号为Seq=U+1;表示是在收到了服务器端报文的基础上,将其确认号Ack值作为本段报文序号的值。 确认号为Ack=W+1;表示是在收到了服务器端报文的基础上,将其序号Seq值作为本段报文确认号的值。 随后客户端开始在TIME-WAIT阶段等待2MSL |
![image-20210106202845874](https://gitee.com/firefrom/pics/raw/master/Net/image-20210106202845874.png)
等待2MSL原因:确认服务器端是否收到客户端发出的ACK确认报文
拥塞控制
网络中的10大主要问题之一
流量控制:发送方不要发送得太快以至于接收方无法处理
拥塞:太多的源发送的太多太快的数据,使网络来不及处理。
表现:
- 丢包(路由器缓冲区溢出)
- 长时延(路由器缓冲区中排队)
对丢失的分组重传,不能解决网络拥塞问题
产生拥塞控制时遏制 发送方
- 网络拥塞如何从上层得到的服务中反映出来;
- 如何避免网络拥塞,或对其作出反应。
拥塞原因与开销(代价)
拥塞原因:资源未被充分利用
拥塞的代价:端系统得到很差的服务性能
讨论:随着主机增加发送速率是网络变得拥塞时产生的影响。
场景1
两个senders,两个receivers
一个路由器:
无限缓存(两个连接共享,单跳路由):不丢失分组
没有重传
- 拥塞时分组延迟太大
- 达到最大throughput
网络拥塞代价:当分组到达速率接近链路容量时,分组排队时延非常大。
吞吐率与时延
场景2
两个senders,两个receivers
一个路由器, 有限缓存
拥塞的代价:
- 对给定的”goodput”,要做更多的工作 (重传)
- 造成资源的浪费
场景3
四个发送方
多跳
超时/重传
![image-20210106212322989](https://gitee.com/firefrom/pics/raw/master/Net/image-20210106212322989.png)
拥塞:
- 当分组被drop时,任何用于该分组的“上游”传输能力全都被浪费掉
拥塞控制方法
根据网络层是否为运输层拥塞控制提供明确的帮助
端到端拥塞控制 | 网络辅助的拥塞控制 |
---|---|
网络层没有为运输层拥塞控制提供明确的支持。 | 网络层构件 (即路由器)向发送方提供关于网络拥塞状态的明确反馈信息。 |
端系统必须通过对网络行为的观察 (如分组丢失与时延)来推断网络中是否存在拥塞。 | 简单的拥塞指示(1bit):SNA, DECbit, TCP/IP ECN, ATM) |
用于TCP的拥塞控制 | 指示发送方应该采取何种速率 |
TCP的拥塞控制
端到端控制 (没有网络辅助)
由发送方根据感知到的拥塞程度,来限制其发送流量的速率。
-
无拥塞:增加发送速率
- 有拥塞:降低发送速率
如何限制发送速率
设置拥塞窗口CongWin:对发送方向网络的发送流量速率进行限制。
- 发送方中未被确认的数据量小于拥塞窗口。
- 通过调节CongWin值,调整发送速率。
如何感知拥塞
- 丢失事件: 超时或者 3个重复ACK
- 发生丢失事件后,TCP发送方降低速率(拥塞窗口)。
拥塞时处理方式
AIMD(加增倍减算法)
逐渐增加发送速率,谨慎探测可用带宽,直到发生loss
-
Additive Increase: 每个RTT将CongWin增大一个MSS——拥塞避免
-
Multiplicative Decrease: 发生loss后将CongWin减半
慢启动 SS
初始时可用带宽远远大于初始速率,窗口呈指数型增长,在CongWin达到Loss事件前1/2变为指数增长
时段 | 动作 | 细节 |
---|---|---|
TCP连接刚建立时 | CongWin = 1 (表示一个最大段长); 每个RTT将CongWin翻倍 收到每个ACK进行操作 | 可用带宽可能远远高于初始速率;希望快速增长 |
发生拥塞控制时 | 当CongWin达到Loss事件前值的1/2时,窗口大小由指数增长转变为线性增长;使用变量Threshold | |
情况1:3个重复的ACKS(网络还能传输些segment(网络还能传输些segment) | CongWin切到一半,然后线性增长 | |
情况2:Timeout事件 | CongWin切到一半,然后线性增长; CongWin直接设为1个MSS 然后指数增长 |
![image-20210107212631716](https://gitee.com/firefrom/pics/raw/master/Net/image-20210107212631716.png)
例题
![image-20210107213430369](https://gitee.com/firefrom/pics/raw/master/Net/image-20210107213430369.png)