事前提一嘴
室友考完研了,下一年就是我了,真不想和他们一起考,压力太大了,这里分享一点笔记吧
采用王道考研的书以及视频,去掉了一些书上的废话,加上了视频中的重点,最后总结出来的
如有侵权,即可删除
传输层
考纲内容
- 传输层提供的服务
传输层的功能;传输层寻址与端口;无连接服务和面向对象服务 - UDP
UDP数据报;UDP校验 - TCP
TCP段;TCP可靠传输;TCP流量控制与拥塞控制
传输层是整个网络体系结构中的关键层次。要求掌握传输层再计算机网络中的低位、功能、工作方式及原理等,掌握UDP及TCP(如首部格式、可靠传输、流量控制、拥塞控制、连接管理等)
其中TCP报文分析、流量控制与拥塞控制机制,出选择题、综合题的概率均较大,因此要将其工作原理透彻掌握,以便能在具体题目中灵活运用
传输层提供的服务
传输层的功能
从通信和信息处理的⻆度看,传输层**为应用层提供通信服务
**
传输层属于**面向通信部分的最高层
,同时也是用户功能中的最低层
**
传输层位于网络层之上,为运行在**不同主机上的进程
之间提供了逻辑通信
网络层提供主机
之间的逻辑通信
即使网络层协议不可靠(网络层协议使分组丢失、混乱或重复),传输层同样能为应用程序提供可靠的服务
**
网络的边缘部分的两台主机使用网络核心部分的功能进行端到端的通信时,只有主机的协议栈才有传输层和应用层
,而**路由器在转发分组时都只用到下三层的功能
**
即在通信子网中没有传输层,传输层只存在于通信子网以外的主机中
传输层的功能
-
传输层**
提供应用进程之间的逻辑通信
(即端到端的通信
**)
与网络层的区别是,网络层提供的是主机之间的逻辑通信从网络层来说,通信的双方是两台主机,IP数据报的首部给出了这两台主机的IP地址 但“两台主机之间的通信”实际上是两台主机中的应用进程之间的通信,应用进程之间的通信又称端到端的逻拜通信 “逻辑通信”的意思是:传输层之间的通信好像是沿水平方向传送数据,但事实上这两个传输层之间并没有一条水平方向的物理连接
-
复用和分用
复用是指发送方不同的应用进程都可使用同一个传输层协议传送数据
分用是指接收方的传输层在剥去报文的首部后能够把这些数据正确交付到目的应用进程注意:网络层也有复用分用的功能 但网络层的复用是指发送方不同协议的数据都可以封装成IP数据报发送出去 分用是指接收方的网络层在剥去首部后把数据交付给相应的协议
-
传输层还要对收到的报文进行**
差错检测(首部和数据部分)
**
而网络层只检查IP数据报的首部,不检验数据部分是否出错 -
提供两种不同的传输协议,即**
面向连接的TCP
和无连接的UDP
**
而网络层无法同时实现两种协议,即在网络层要么只提供面向连接的服务
如虚电路:要么只提供无连接服务,如数据报,而不可能在网络层同时存在这两种方式
传输层**向高层用户屏蔽了低层网络核心的细节
**(如网络拓扑、路由协议等)
它使应用进程看⻅的是在两个传输层实体之间好像有一条端到端的逻辑通信信道
这条逻辑通信信道对上层的表现却因传输层协议不同而有很大的差别
当传输层**采用面向连接的TCP
时,尽管下面的网络是不可靠的(只提供尽最大努力的服务),但这种逻辑通信信道就相当于一条全双工的可靠信道
**
当传输层**采用无连接的UDP
时,这种逻辑通信信道仍然是一条不可靠信道
**
传输层的寻址与端口
复用:应用层所有的应用进程都可以通过传输层再传输到网络层
分用:传输层从网络层收到数据后交付指明的应用进程
𧍒口的作用
- 让**
应用层
的各种应用进程将其数据通过端口向下交付给传输层
** - 让**
传输层
知道应当将其报文段中的数据向上通过端口交付给应用层相应的进程
**
端口是**传输层服务访问点(TSAP)
**
在传输层的作用类似于IP地址在网络层的作用或MAC地址在数据链路层的作用,只不过IP地址和MAC地址标识的是主机,而**端口标识的是主机中的应用进程
**
数据链路层的SAP是MAC地址,网络层的SAP是IP地址,传输层的SAP是端口
在协议栈层间的抽象的协议端口是软件端口,它与路由器或交换机上的硬件端口是完全不同的概念
硬件端口是不同硬件设备进行交互的接口
软件端口是**应用层的各种协议进程与传输实体进行层间交互的一种地址
**
传输层使用的是软件端口
端口号
应用进程通过端口号进行标识,端口号⻓度为**16bit
**,能够表示 65536(216) 个不同的端口号
端口号**只具有本地意义
,即端口号只标识本计算机应用层中的各进程
**,在因特网中不同计算机的相同端口号是没有联系的
根据端口号范围可将端口分为两类:
-
服务器端使用的端口号:
1、熟知端口号,数值为**0 ~ 1023
**,这些端口号被指派给了TCP/IP最重要的一些应用程序 一些常用的熟知端口号如下:
2、登记端口号,数值为**1024 ~ 49151
**,供没有熟知端口号的应用程序使用的
使用这类端口号必须在IANA登记,以防止重复 -
客户端使用的端口号:数值为**
49152~65535
**
由于这类端口号仅在客户进程运行时才动态地选择,因此又称**短暂端口号
(也称临时端口
**)
通信结束后,刚用过的客户端口号就不复存在,从而这个端口号就可供其他客户进程以后使用
套接字
在网络中**通过IP地址来标识和区别不同的主机
,通过端口号来标识和区分一台主机中的不同应用进程
**
端口号拼接到IP地址即构成**套接字(Socket)
**
在网络中**采用发送方和接收方的套接字来识别端点
**
套接字,实际上是一个**通信端点
,即:套接字Socket=(IP地址:端口号)
**
它**唯一地标识网络中的一台主机和其上的一个应用(进程)
**
在网络通信中,主机A发给主机B的报文段包含目的端口号和源端口号
源端口号是“返回地址”的一部分,即当B需要发回一个报文段给A时,B到A的报文段中的目的端口号便是A到B的报文段中的源端口号(完全的返回地址是A的IP地址和源端口号)
无连接服务与面向连接服务
面向连接服务:在通信双方进行通信之前,必须先建立连接
,在通信过程中,整个连接的情况一直被实时地监控和管理
。通信**结束后
,应该释放这个连接
**
无连接服务:两个实体之间的通信**不需要先建立好连接
,需要通信时,直接将信息发送到“网络”中,让该信息的传递在网上尽力而为地往目的地传送
**
TCP/IP协议族在IP层之上使用了两个传输协议:
面向连接的传输控制协议(TCP)
,采用TCP时,传输层向上提供的是一条**全双工的可靠逻辑信道
**
TCP提供面向连接的服务,在传送数据之前必须先建立连接,数据传送结束后要释放连接
TCP**不提供广播或组播服务
**
由于TCP提供面向连接的可靠传输服务,因此**不可避免地增加了许多开销
,如确认、流量控制、计时器及连接管理等。这不仅使协议数据单元的头部增大很多,还要占用许多的处理机资源
TCP主要适用于可靠性更重要的场合
,如文件传输协议(FTP)、超文本传输协议(HTTP)、远程登录(TELNET)等
特点:可靠、面向连接、时延大、适用于大文件
**无连接的用户数据报协议(UDP)
,采用UDP时,传输层向上提供的是一条**不可靠的逻辑信道
**
UDP是一个无连接的非可靠传输层协议
在IP之上仅提供两个附加服务:多路复用和对数据的错误检查
IP知道怎样把分组投递给一台主机,但不知道怎样把它们投递给主机上的具体应用
UDP在传送数据之前不需要先建立连接,远程主机的传输层收到UDP报文后,不需要给出任何确认
由于UDP比较简单,因此**执行速度比较快、实时性好
**
使用UDP的应用主要包括小文件传送协议(TFTP)、DNS、SNMP和实时传输协议(RTP)
特点:无连接、时延小、适用于小文件
注:
1、IP数据报和UDP数据报的区别:
IP数据报在网络层要经过路由的存储转发
UDP数据报在传输层的端到端的逻信道中传输,封装成IP数据报在网络层传输时,UDP数据报的信息对路由不可⻅
2、TCP和网络层虚电路的区别:
TCP报文段在传输层抽象的逻拜信道中传输,对路由器不可⻅
虚电路所经过的交换结点都必须保存虚电路状态信息
在网络层若采用虚电路方式,则无法提供无连接服务
而传输层采用TCP不影响网络层提供无连接服务
UDP协议
UDP概述
UDP仅在IP的数据报服务之上增加了两个最基本的服务:复用和分用以及差错检测
UDP的优点
UDP无须建立连接
。减少了开销和发送数据之前的时延
如果DNS运行在TCP而非UDP上,那么DNS的速度会慢很多。HTTP使用TCP而非UDP,是因为对于基于文本数据的Web网⻚来说,可靠性是至关重要的无连接状态
。
TCP需要在端系统中维护连接状态。连接状态包括接收和发送缓存、拥塞控制参数和序号与确认号参数
UDP不维护连接状态,也不跟踪这些参数
因此,某些专用应用服务器使用UDP时,一般都**能支持更多的活动客户机
**分组首部开销小
。TCP有20B的首部开销,而**UDP仅有8B的开销
**应用层能更好地控制要发送的数据和发送时间
。UDP**没有拥塞控制
**,因此网络中的拥塞不会影响主机的发送效率
某些实时应用要求以稳定的速度发送,能容忍一些数据的丢失,但不允许有较大的时延,而UDP正好满足这些应用的需求UDP支持一对一、一对多、多对一和多对多的交互通信
UDP**常用于一次性传输较少数据的网络应用
,如DNS、SNP等,因为对于这些应用,若采用TCP,则将为连接创建、维护和拆除带来不小的开销
UDP也常用于多媒体应用
**(如IP电话、实时视频会议、流媒体等),显然,可靠数据传输对这些应用来说并不是最重要的,但TCP的拥塞控制会导致数据出现较大的延迟,这是它们不可容忍的
UDP**不保证可靠交付
,使用最大努力交付,但这并不意味着应用对数据的要求是不可靠的,所有维护可靠性的工作可由用户在应用层来完成
**
UDP是**面向报文
的,适合一次性传输少量数据的网络应用
发送方UDP对应用层交下来的报文,在添加首部后就向下交付给IP层,一次发送一个报文,既不合并,也不拆分
,而是保留这些报文的边界
接收方UDP对IP层交上来UDP数据报,在去除首部后就原封不动地交付给上层应用进程,一次交付一个完整的报文
**
UDP**无拥塞控制
**,适合很多实时应用
报文不可分割,是UDP数据报处理的最小单位
。因此,应用程序必须选择合适大小的报文
若报文太**⻓
,UDP把它交给IP层后,可能会导致分片
**
若报文太**短
,UDP把它交给IP层后,会使IP数据报的首部的相对⻓度太大
**
两者都**会降低IP层的效率
**
UDP的首部格式
UDP数据报包含两部分:UDP首部和用户数据
UDP首部有**8B
,由4个字段组成,每个字段的⻓度都是2B
**
各字段意义如下:
- 源端口。源端口号。在需要对方回信时选用,不需要时可用全0
- 目的端口。目的端口号。这在终点交付报文时必须使用到
- ⻓度。UDP数据报的⻓度(包括首部和数据),其最小值是8(仅有首部)
- 校验和。检测UDP数据报在传输中是否有错。有错就丢弃。该字段是可选的,当源主机不想计算校验和时;则直接令该字段为全0
当传输层从IP层收到UDP数据报时,就根据首部中的目的端口,把UDP数据报通过相应的端口上交给应用进程
如果接收方UDP发现收到的报文中的目的端口号不正确(即不存在对应于端口号的应用进程),那么就丢弃该报文,并由ICMP发送“端口不可达”差错报文给发送方
UDP校验
在计算校验和时,要**在UDP数据报之前增加12B的伪首部
**,伪首部并不是UDP的真正首部
只是在计算校验和时,临时添加在UDP数据报的前面,得到一个临时的UDP数据报
校验和就是按照这个临时的UDP数据报来计算的
伪首部既不向下传送又不向上递交,而只是为了计算校验和
UDP数据报的伪首部各字段的内容:
UDP校验和的计算方法和IP数据报首部校验和的计算方法相似
不同的是,IP数据报的校验和只检验IP数据报的首部,但**UDP的校验和则检查首部和数据部分
**
- 发送方首先把全零放入校验和字段并添加伪首部,然后把UDP数据报视为许多16位的字串接起来
- 若UDP数据报的数据部分不是偶数个字节,则要在数据部分末尾填入一个全零字节(但此字节不发送)
然后按二进制反码计算出这些16位字的和,将此和的二进制反码写入校验和字段,并发送 - 接收方把收到的UDP数据报加上伪首部(如果不为偶数个字节,那么还需要补上全等字节)后,按二进制反码求这些16位字的和
- 当**
无差错时其结果应为全1
**,否则就表明有差错出现,接收方就应该丢弃这个UDP数据报
本例中,UDP数据报的⻓度是15B(不含伪首部),因此需要添加一个全0字节
注:
1、校验时,若UDP数据报部分的⻓度不是偶数个字节,则需填入一个全0字节,但是此字节和伪首部一样,是不发送的
2、如果UDP校验和校验出UDP数据报是错误的,那么可以丢弃,也可以交付给上层,但是需要附上错误报告,即告诉上层这是错误的数据报
3、通过伪首部,不仅可以检查源端口号、目的端口号和UDP用户数据报的数据部分,还可以检查IP数据报的源IP地址和目的地
这种简单的差错校验方法的校错能力并不强,但它的好处是**简单、处理速度快
**
TCP协议
TCP协议的特点
TCP是**在不可靠的IP层之上实现的可靠的数据传输协议
,它主要解决传输的可靠、有序、无丢失和不重复问题
**
主要特点
-
TCP是**
面向连接
的传输层协议
,TCP连接是一条逻辑连接
** -
每一条TCP连接**
只能有两个端点
,每一条TCP连接只能是点到点的(一对一)
** -
TCP**
提供可靠交付的服务
,保证传送的数据无差错、不丢失、不重复且有序
** -
TCP提供**
全双工通信
,允许通信双方的应用进程在任何时候都能发送数据,为此TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据
**
发送缓存用来暂时存放以下数据: 1、发送应用程序传送给发送方TCP**
准备发送的数据
**
2、TCP**已发送但尚未收到确认的数据
**接收缓存用来暂时存放以下数据:
1、按序到达但尚未被接收应用程序读取的数据
2、不按序到达的数据
-
TCP是**
面向字节流
的,虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序交下来的数据仅视为一连串的无结构的字节流
**
TCP和UDP在发送报文时所采用的方式完全不同
UDP报文的⻓度**由发送应用进程决定
**
TCP报文的⻓度**根据接收方给出的窗口值和当前网络拥塞程度来决定
**
如果应用进程传送到TCP缓存的**数据块太⻓
,TCP就把它划分得短一些再传送
**
如果**太短
,TCP也可以等到积累足够多的字节后再构成报文段发送
**出去
TCP报文段
TCP传送的数据单元称为报文段
TCP报文段既可以用来**运载数据
,又可以用来建立连接、释放连接和应答
**
一个TCP报文段分为**首部和数据
两部分,整个TCP报文段作IP数据报的数据部分封装在IP数据报
**中
首部的**前20B是固定的
**
TCP首部**最短为20B
,后面有4N字节是根据需要而增加的选项,⻓度为4B的整数倍
**
各字段意义
- 源端口和目的端口。各占2B
端口是传输层与应用层的服务接口
,传输层的复用和分用功能都要通过端口实现
- 序号。占4B,范围为 0 ~ 232 - 1 ,共**
22个序号
**
TCP是面向字节流的(即TCP传送时是逐个字节传送的),所以TCP连接传送的字节流中的每个字节都按顺序编号
序号字段的值:本报文段所发送的数据的第一个字节的序号
例如,一报文段的序号字段值是301,而携带的数据共有100B,表明本报文段的数据的最后一个字节的序号是400,因此下一个报文段的数据序号应从401开始 - 确认号。占4B,是**
期望收到对方下一个报文段的第一个数据字节的序号
**
若**确认号为N
,则表明到序号N - 1为止的所有数据都已正确收到
**
例如,B正确收到了A发送过来的一个报文段,其序号字段是501,而数据⻓度是200B(序号501~700),这表明B正确收到了A发送的到序号700为止的数据。因此B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701 - 数据偏移(即首部⻓度)。占4位,
指出TCP报文段的数据起始处距离TCP报文段的起始处有多远
“数据偏移”的单位是**32位(4B)
**
由于4位二进制数能表示的最大值为15,因此**TCP首部的最大⻓度次60B
** - 保留。占6位,保留为今后使用,但目前应置为0
- 紧急位URG。当**
URG=1时,表明紧急指针字段有效
**
它**告诉系统此报文段中有紧急数据,应尽快传送
(相当于高优先级的数据)
但URG需要和首部中紧急指针字段配合使用
,即数据从第一个字节到紧急指针所指字节就是紧急数据
** - 确认位ACK。
仅当ACK = 1时确认号字段才有效
。当ACK=0时,确认号无效
TCP规定,在**连接建立后所有传送的报文段都必须把ACK置1
** - 推送位PSH(Push)。接收方TCP**
收到PSH=1的报文段
,就尽快地交付给接收应用进程
**,而不再等到整个缓存都填满了后再向上交付 - 复位位RST(Reset)。当**
RST=1时,表明TCP连接中出现严重差错
(如主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接
** - 同步位SYN。当**
SYN=1时
表示这是一个连接请求或连接接受报文
**
当**SYN=1,ACK=0
时,表明这是一个连接请求报文
**
对方若**同意建立连接
,则应在响应报文中使用SYN=1,ACK=1
** - 终止位FIN(Finish)。用来**
释放一个连接
**
当**FIN=1时
,表明此报文段的发送方的数据已发送完毕
,并要求释放运输连接
** - 窗口。占2B,范围为 0 ~ 216 - 1
指出现在**允许对方发送的数据量
**,接收方的数据缓存空间是有限的,因此用窗口值作为接收方让发送方设置其发送窗口的依据
例如,设确认号是701,窗口字段是1000。这表明,从701号算起,发送此报文段的一方还有接收1000字节数据(字节序号为701~1700)的接收缓存空间 - 校验和。占2B。校验和字段**
检验的范围包括首部和数据
两部分
在计算校验和时,和UDP一样,要在TCP报文段的前面加上12B的伪首部
**(伪首部的协议字段为6,⻓度为TCP长度) - 紧急指针。占2B。紧急指针**
仅在URG=1时才有意义
**
指出**在本报文段中紧急数据共有多少字节
**(紧急数据在报文段数据的最前面) - 选项。⻓度可变。TCP最初只规定了一种选项,即**
最大报文段⻓度
**(MSS)
MSS是TCP报文段中的数据字段的最大⻓度(注意仅仅是数据字段) - 填充。这是为了**
使整个首部⻓度是4B的整数倍
**
TCP连接管理
TCP是面向连接的协议,因此每个TCP连接都有三个阶段:连接建立、数据传送和连接释放
TCP连接的管理就是**使运输连接的建立和释放都能正常进行
**
在TCP连接建立的过程中,要解决以下三个问题:
1、要使每一方能够明确知到对方的存在
2、要允许双方协商一些参数(如最大窗口值、是否使用窗口扩大选项、时间戳选项及服务质量等)
3、能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配
TCP把连接作为最基本的抽象,每条TCP连接有两个端点
TCP连接的端口即为**套接字(Socket)
或插口
,每条TCP连接唯一地被通信的两个端点(即两个套接字)确定
**
TCP连接的建立采用**客户/服务器模式
**
主动发起连接建立的应用进程称为客户(Client)
被动等待连接建立的应用进程称为服务器(Server)
TCP连接的建立
连接的建立通常称为**三次握手
**
- 连接建立前,服务器进程处于**
LISTEN(收听)状态
**,等待客户的连接请求 - 第一步:
客户机的TCP
首先向服务器的TCP发送连接请求报文段
这个特殊报文段的首部中的**同步位SYN置1
,同时选择一个初始序号seq = x
**
TCP规定,SYN报文段不能携带数据,但要消耗掉一个序号
TCP**客户进程
进入SYN-SENT(同步已发送)状态
** - 第二步:
服务器的TCP收到连接请求报文段
后
如同意建立连接
,则**向客户机发回确认
,同时也为自己选择一个初始序号seq = y
**
确认报文段不能携带数据,但也要消耗掉一个序号
TCP**服务器进程
进入SYN-RCVD(同步收到)状态
** - 第三步
当**客户机收到确认报文段
后,还要向服务器给出确认
,并为该TCP连接分配缓存和变量
**
确认报文段的ACK位置1
,确认号ack = y + 1
,序号seq = x + 1
该报文段可以携带数据,若不携带数据则不消耗序
TCP**客户进程
进入ESTABLISHED(已建立连接)状态
**
成功进行以上步骤后,就建立了TCP连接,接下来就可以传送应用层数据
TCP提供的是**全双工通信
**,因此通信双方的应用进程在任何时候都能发送数据
注:
服务器端的资源是在第二次握手时分配的
客户端的资源是再完成第三次握手时分配的,这就使得服务器易于收到SYN洪泛攻击
SYN洪泛攻击
SYN洪泛攻击发生再OSI第四层,这种方式利用TCP协议的特性,即三次握手
攻击者发送TCP SYN,SYN是TCP三次握手中的**第一个数据包
**,而当服务器返回ACK后,该攻击者不对其进行再确认,那这个TCP连接就处于挂起状态,也就是所谓的半连接状态,服务器收不到再确认的话,还会重复发送ACK给攻击者,这样会更加浪费服务器的资源
攻击者就对服务器发送非常大量的这种TCP连接,由于每一个都没法完成三次握手,所以再服务器上,这些TCP连接会因为挂起状态而消耗CPU和内存,最后服务器可能死机,就无法为正常用户提供服务了
TCP连接的释放
参与TCP连接的**两个进程中的任何一个都能终止该连接
**
TCP连接的释放过程通常称为**四次握手(四次挥手)
**
- 第一步
客户机
打算关闭连接时,向其TCP发送连接释放报文段
,并**停止发送数据
,主动关闭TCP连接
**
该报文段的**终止位FIN置1
,序号seq = u
,它等于前面已传送过的数据的最后一个字节的序号加1
**
FIN报文段即使不携带数据,也消耗掉一个序号
这时,TCP**客户进程
进入FIN-WAIT-1(终止等待1)状态
**
TCP是全双工的,即可以想象为一条TCP连接上有两条数据通路,发送FIN的一端不能再发送数据
即**关闭了其中一条数据通路,但对方还可以发送数据
** - 第二步
服务器收到连接释放报文段
后即发出确认
确认号ack = u + 1
,序号seq = v
,它**等于前面已传送过的数据的最后一个字节的序号加1
**
然后**服务器
进入CLOSE-WAIT(关闭等待)状态
**
此时,从**客户机到服务器这个方向的连接就释放了
,TCP连接处于半关闭状态
但服务器若发送数据,客户机仍要接收,即从服务器到客户机这个方向的连接并未关闭
** - 第三步
若**服务器
已经没有要向客户机发送的数据
,就通知TCP释放连接
,发出FIN=1的连接释放报文段
**
设该**报文段序号为w
(在半关闭状态服务器可能又发送了一些数据)
还须重复上次已发送的确认号ack = u + 1
**
这时**服务器
进入LAST-ACK(最后确认)状态
** - 第四步
客户机收到连接释放报文段后,必须发出确认
把**确认报文段
中的确认位ACK置1
,确认号ack = w + 1
,序号seq = u + 1
**
此时**TCP连接还未释放
,必须经过时间等待计时器设置的时间2MSL(最⻓报文段寿命)
后,客户机
才进入CLOSED(连接关闭)状态
**
总结如下:
三次握手(建立连接)
- SYN = 1,seq = x
- SYN = 1,ACK = 1,seq = y,ack = x + 1
- ACK = 1,seq = x + 1,ack = y + 1
四次挥手(释放连接)
- FIN = 1,seq = u
- ACK = 1,seq = v,ack = u + 1
- FIN = 1,ACK = 1,seq = w,ack = u + 1
- ACK = 1,seq = u + 1,ack = w + 1
注:关于连接和释放的题目中,ACK、SYN、FIN一定等于1
TCP可靠传输
TCP的任务是**在IP层不可靠的、尽力而为服务的基础上建立一种可靠数据传输服务
**
TCP提供的可靠数据传输服务**保证接收方进程从缓存区读出的字节流与发送方发出的字节流完全一样
**
TCP使用了**校验、序号、确认和重传等机制
**来达到这一目的
其中,TCP的校验机制与UDP校验一样
序号
TCP首部的**序号字段用来保证数据能有序提交给应用层
**
TCP把数据视为一个**无结构但有序的字节流
,序号建立在传送的字节流之上
**,而不建立在报文段之上
TCP连接传送的数据流中的每个字节都编上一个序号
序号字段的值:本报文段所发送的数据的第一个字节的序号
假设A和B之间建立了一条TCP连接,A的发送缓存区中共有10B
序号从0开始标号,第一个报文包含第0 ~ 2个字节,则该TCP报文段的序号是0,第二个报文段的序号是3
确认
TCP首部的**确认号是期望收到对方的下一个报文段的数据的第一个字节的序号
**
如果接收方B已收到第一个报文段,此时B希望收到的下一个报文段的数据是从第3个字节开始的,那么B发送给A的报文中的确认号字段应为3
发送方缓存区
会继续存储那些已发送但未收到确认的报文段
,以便**在需要时重传
**
TCP**默认使用累积确认
,即TCP只确认数据流中至第一个丢失字节为止的字节
**
接收方B收到了A发送的包含字节0 ~ 2及字节6 ~ 7的报文段
由于某种原因,B还未收到字节3~5的报文段,此时B仍在等待字节3(和其后面的字节)
因此B到A的下一个报文段将确认号字段置为3
重传
有两种事件会导致TCP对报文段进行重传:超时和冗余ACK
- 超时
TCP每发送一个报文段,就对这个报文段设置一次计时器
计时器设置的重传时间到期但还未收到确认时,就要重传这一报文段
为了计算超时计时器的重传时间,TCP采用一种自适应算法,它**记录一个报文段发出的时间,以及收到相应确认的时间
,这两个时间之差称为报文段的往返时间(RTT)
**
TCP保留了RTT的一个**加权平均往返时间RTTs
,它会随新测量RTT样本值的变化而变化
**
显然,超时计时器设置的**超时重传时间(RTO)应略大于RTTs
,但也不能大太多,否则当报文段丢失时,TCP不能很快重传,导致数据传输时延大
** - 冗余ACK(冗余确认)
超时触发重传存在的一个问题是**超时周期往往太⻓
**
发送方通常**可在超时事件发生之前通过注意所谓的冗余ACK来较好地检测丢包情况
**
冗余ACK:再次确认某个报文段的ACK
,而发送方先前已经收到过该报文段的确认
TCP规定**每当比期望序号大的失序报文段到达时,就发送一个冗余ACK,指明下一个期待字节的序号
**
TCP规定当发送方**收到对同一个报文段的3个冗余ACK时,就可以认为跟在这个被确认报文段之后的报文段已经丢失
**
冗余ACK还被用在**拥塞控制
**中
TCP流量控制
TCP提供流量**控制服务来消除发送方(发送速率太快)使接收方缓存区溢出的可能性
**
因此可以说流量控制是一个**速度匹配服务
**(匹配发送方的发送速率与接收方的读取速率)
TCP提供一种**基于滑动窗口协议的流量控制机制
**
- 接收窗口rwnd:通信过程中,接收方根据自己接收缓存的大小,动态地调整发送方的发送窗口大小
即调整TCP报文段首部中的**窗口字段值
,来限制发送方向网络注入报文的速率
**
rwnd即**接收方允许连续接收的最大能力
,单位是字节
** - 拥塞窗口cwnd:发送方根据其对当前网络拥塞程度的估计而确定的窗口值
其大小与网络的**带宽和时延密切相关
**
例如,在通信中,有效数据只从A发往B,而B仅向A发送确认报文
这时B可以通过设置确认报文段首部的窗口字段来将rwnd通知给A
发送方A总是根据最新收到的rwnd值来限制自己发送窗口的大小
从而将未确认的数据量控制在rwnd大小之内,保证A不会使B的接收缓存溢出
A的**发送窗口的实际大小取rwnd和cwnd中的最小值
**
设A向B发送数据,在连接建立时,B告诉A:“我的接收窗口rwnd = 400”
接收方主机B进行了三次流量控制,这三个报文段都设置了ACK=1,只有在ACK=1时确认号字段才有意义
第一次把窗口减小到rwnd = 300
第二次又减到rwnd = 100
最后减到rwnd = 0,即不允许发送方再发送数据
这使得发送方暂停发送的状态将持续到B重新发出一个新的窗口值为止
传输层和数据链路层的流量控制的区别
传输层定义端到端用户之间的流量控制
数据链路层定义两个中间的相邻结点的流量控制
数据链路层的滑动窗口协议的窗口大小不能动态变化
传输层的则可以动态变化
TCP拥塞控制
拥塞控制是指防止过多的数据注入网络,保证网络中的路由器或链路不致过载
出现拥塞时,端点并不了解拥塞发生的细节,对通信连接的端点来说,拥塞往往**表现为通信时延的增加
**
拥塞控制与流量控制的区别
拥塞控制是让网络能够承受现有的网络负荷,是一个全局性的过程,涉及所有的主机、所有的路由器,以及与降低网络传输性能有关的所有因素
流量控制往往是指点对点的通信量的控制,是个端到端的问题(接收端控制发送端),它所要做的是抑制发送端发送数据的速率,以便使接收端来得及接收
当然,拥塞控制和流量控制也有相似的地方,即它们都通过控制发送方发送数据的速率来达到控制效果
拥塞控制的4中算法:慢开始、拥塞避免、快重传和快恢复
发送方在确定发送报文段的速率时,既要根据接收方的接收能力,又要从全局考虑不要使网络发生拥塞
TCP协议要求发送方维护以下两个窗口:
- 接收窗口rwnd,
接收方
根据目前接收缓存大小所许诺的最新窗口值,反映接收方的容量
由接收方根据其放在TCP报文的首部的窗口字段通知发送方 - 拥塞窗口cwnd,
发送方
根据自己估算的网络拥塞程度而设置的窗口值,反映网络的当前容量
只要网络未出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去
只要网络出现拥塞,拥塞窗口就减小一些,以减少注入网络的分组数
发送窗口的上限值应取接收窗口rwnd和拥塞窗口cwnd中较小的一个,即
发送窗口的上限值 = min[rwnd,cwnd]
注:假设接收方总是有足够大的缓存空间,因而发送窗口大小由网络的拥塞程度决定,也就是说,可以将发送窗口等同为拥塞窗口
慢开始和拥塞避免
1、慢开始算法
在TCP刚刚连接好并开始发送TCP报文段时,先令**拥塞窗口cwnd = 1
,即一个最大报文段⻓度MSS
每收到一个对新报文段的确认
后,将cwnd加1
**,即增大一个MSS
用这样的方法逐步增大发送方的cwnd,可使分组注入网络的速率更加合理
慢开始的“慢”并不是指拥塞窗口cwnd的增⻓速率慢,而是指在TCP开始发送报文段时先设置cwnd = 1
使得发送方在开始时只发送一个报文段(目的是试探一下网络的拥塞情况),然后再逐渐增大cwnd
这对防止网络出现拥塞是一个非常有力的措施
使用慢开始算法后,每经过一个传输轮次(即往返时延RTT),cwnd就会加倍
,即cwnd的值随传输轮次指数规律增⻓
这样,慢开始一直把cwnd增大到一个规定的慢开始⻔限ssthresh(阈值),然后改用拥塞避免算法
例:
A向B发送数据,发送方先置拥塞窗口cwnd = 1
A发送第一个报文段,A收到B对第一个报文段的确认后,把cwnd从1增大到2
A接着发送两个报文段,A收到B对这两个报文段的确认后,把cwnd从2增大到4
下次就可一次发送4个报文段
2、拥塞避免算法
拥塞避免算法的思路是**让拥塞窗口cwnd缓慢增大
**
每**经过一个往返时延RTT就把发送方的拥塞窗口cwnd加1
**,而不是加倍,使拥塞窗口cwnd按线性规律缓慢增⻓(即加法增大),这比慢开始算法的拥塞窗口增⻓速率要缓慢得多
- 当**
cwnd < ssthresh
时,使用慢开始算法
** - 当**
cwnd > ssthresh
时,停止使用慢开始算法而改用拥塞避免算法
** - 当**
cwnd = ssthresh
时,既可使用慢开始算法
,又可使用拥塞避免算法
**
3、网络拥塞的处理
无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(未按时收到确认),就要把慢开始⻔限ssthresh设置为出现拥塞时的发送方的cwnd值的一半
(但不能小于2)
然后把**拥塞窗口cwnd重新设置为1
,执行慢开始算法
**
目的是**迅速减少主机发送到网络中的分组数
**,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完
慢开始和拥塞避免算法的实现过程
- 初始时,拥塞窗口置为1,即**
cwnd = 1
,慢开始⻔限置为16,即ssthresh = 16
** - 慢开始阶段,cwnd的初值为1,以后发送方每收到一个确认ACK,cwnd值加1,也即经过每个传输轮次(RTT),cwnd星指数规律增⻓
当拥塞窗口cwnd增⻓到慢开始⻔限ssthresh时(即**当cwnd = 16
时),就改用拥塞避免算法
**,cwnd按线性规律增⻓ 假定cwnd = 24时网络出现超时
,更新ssthresh值为12(即**变为超时时cwnd值的一半
),cwnd重置为1
,并执行慢开始算法
,当cwnd = 12时,改为执行拥塞避免算法
**
注:
在慢开始(指数级增⻓)阶段
若2cwnd > ssthresh,则下一个RTT后的cwnd等于ssthresh,而不等于2cwnd,即cwnd不能跃过ssthresh值
如上例所示,在第16个轮次时cwnd = 8、ssthresh = 12,则在第17个轮次时cwnd = 12,而不等于16
在慢开始和拥塞避免算法中使用了**乘法减小
和加法增大
**方法
乘法减小:不论是在慢开始阶段还是在拥塞避免阶段,只要出现超时(即很可能出现了网络拥塞),就把慢开始⻔限值ssthresh设置为当前拥塞窗口的一半(并执行慢开始算法)
。当网络频繁出现拥塞时,sthresh值就下降得很快,以大大减少注入网络的分组数。
加法增大:是指执行拥塞避免算法后,在收到对所有报文段的确认后(即经过一个RTT),就把拥塞窗口cwnd增加一个MSS大小,使拥塞窗口缓慢增大,以防止网络过早出现拥塞
拥塞避免并不能完全避免拥塞
利用以上措施要完全避免网络拥塞是不可能的
拥塞避免是指在拥塞避免阶段把拥塞窗口控制为按线性规律增⻓,使网络比较不容易出现拥塞
快重传和快恢复
1、快重传
快重传技术**使用了冗余ACK来检测丢包的发生
**,冗余ACK也用于网络拥塞的检测
快重传并非取消重传计时器,而是在某些情况下**可更早地重传丢失的报文段
**
当**发送方连续收到三个重复的ACK报文
时,直接重传
**对方尚未收到的报文段,而不必等待那个报文段设置的重传计时器超时
2、快恢复
快恢复算法的原理:
当发送方**连续收到三个冗余ACK
(即重复确认)时,执行乘法减小
算法,把慢开始⻔限ssthresh设置为此时发送方cwnd的一半
。这是为了预防网络发生拥塞
**
然后开始执行**拥塞避免算法(加法增大)
**,使拥塞窗口缓慢地线性增大
由于**跳过了拥塞窗口cwnd从1起始的慢开始过程
**,所以被称为快恢复
快恢复算法的实现过程(虚线为慢开始的处理过程)
在流量控制中,发送方发送数据的量由接收方决定
在拥塞控制中,则由发送方自己通过 检测网络状况来决定
实际上,慢开始、拥塞避免、快重传和快恢复几种算法是同时应用在拥塞控制机制中
四种算法使用的总结:
在TCP连接建立和网络出现超时时,采用馒开始和拥塞避免算法
当发送方接收到冗余ACK时,采用快重传和快恢复算法
接收方的缓存空间总是有限的
因此,发送方发送窗口的实际大小由流量控制和拥塞控制共同决定
当题目中**同时出现接收窗口(rwnd)和拥塞窗口(cwnd)时,发送方实际的发送窗口大小是由rwnd和cwnd中较小的那一个确定的
**
疑难点
MSS设置得太大或太小会有什么影响
规定最大报文段MSS的大小并不是考虑到接收方的缓存可能放不下TCP报文段。实际上,MSS与接收窗口没有关系
TCP的报文段的数据部分,至少要加上40B的首部(TCP首部至少20B和IP首部至少20B),才能组装成一个IP数据报
若选择较小的MSS值,网络的利用率就很低
设想在极端情况下,当TCP报文段中只含有1B的数据时,在IP层传输的数据报的开销至少有40B
这样,网络的利用率就不会超过1/41
到了数据链路层还要加上一些开销,网络的利用率进-步降低
但反过来,若TCP报文段很⻓,那么在IP层传输时有可能要分解成多个短数据报片,在终端还要把收到的各数据报片装配成原来的TCP报文段
传输有差错时,还要进行重传。这些都会使开销增大
因此,MSS应尽量大一些,只要在IP层传输时不要再分片就行
由于IP数据报所经历的路径是动态变化的,在一条路径上确定的不需要分片的MSS,如果改走另一条路径,就可能需要进行分片
因此,最佳的MSS是很难确定的
MSS的默认值为536B,因此在因特网上的所有主机都能接收的报文段⻓度是536+20(xTCP固定首部⻓度)=556B
为何不采用“三次握手”释放连接,且发送最后一次握手报文后要等待2MSL的时间呢?
1、保证A发送的最后一个确认报文段能够到达B
如果A不等待2MSL,若A返回的最后确认报文段丢失,则B不能进入正常关闭状态,而A此时己经关闭,也不可能再重传
2、防止出现“已失效的连接请求报文段”
A在发送最后一个确认报文段后,再经过2MSL可保证本连接持续的时间内所产生的所有报文段从网络中消失
注意:服务器结束TCP连接的时间要比客户机早一些,因为客户机最后要等待2MSL后才可进入CLOSED状态
为什么不采用“两次握手”建立连接呢?
为了防止两次握手情况下已失效的连接请求报文段突然又传送到服务器而产生错误
客户A向服务器B发出TCP连接请求,第一个连接请求报文在网络的某个结点⻓时间滞留,A超时后认为报文丢失,于是再重传一次连接请求,B收到后建立连接
数据传输完毕后双方断开连接
而此时,前一个滞留在网络中的连接请求到达服务器B,而B认为A又发来连接请求
此时若使用“三次握手”,则B向A返回确认报文段,由于是一个失效的请求,因此A不予理睬,建立连接失败
若采用的是“两次握手”,则这种情况下B认为传输连接已经建立,并一直等待A传输数据,而A此时并无连接请求,因此不予理睬,这样就造成了B的资源白白浪费
是否TCP和UDP都需要计算往返时间RTT?
往返时间RTT仅对传输层TCP协议才很重要,因为TCP要根据RTT的值来设置超时计时器的超时时间
UDP没有确认和重传机制,因此RTT对UDP没有什么意义
假定在一个互联网中,所有链路的传输都不出现差错,所有结点也都不会发生故障。试问在这种情况下,TCP的“可靠交付”的功能是否就是多余的?
不是多余的
TCP的“可靠交付”功能在互联网中起着至关重要的作用
至少在以下的情况下,TCP的“可靠交付”功能是必不可少的
1、每个IP数据报独立地选择路由,因此在到达目的主机时有可能出现失序
2、由于路由选择的计算出现错误,导致IP数据报在互联网中转圈。最后数据报首部中的生存时间(TTL)的数值下降到零。这个数据报在中途就被丢失
3、某个路由器突然出现很大的通信量,以致路由器来不及处理到达的数据报。因此有的数据报被丢弃
以上列举的问题表明:必须依靠TCP的“可靠交付”功能才能保证在目的主机的目的进程中接收到正确的报文