3.1 概述和运输层服务
运输层协议为运行在不同主机上的应用进程之间提供了逻辑通信
应用进程使用运输层提供的逻辑通信功能彼此发送报文,而不用考虑承载这些报文的物理基础设施的细节。
将运输层分组称为报文段
TCP和UDP的基本责任是,将两个端系统间IP的交付服务扩展为运行在端系统上的两个进程之间的交付服务。将主机间交付扩展到进程间交付被称为运输层的多路复用与多路分解。
3.2 多路复用与多路分解
在目的主机上,运输层从网络层接收报文段,运输层负责将这些报文段中的数据交付给主机上运行的适当应用程序进程。
每个运输层报文段中具有几个字段,使接收主机将它定向到适当的套接字
在接收端,运输层检查这些字段,标识出接收套接字,进而将报文段定向到该套接字。
- 将运输层报文段中的数据交付到正确的套接字称为多路分解。
- 在源主机从不同套接字中手机数据块,并为每个数据块封装上首部信息从而生成报文段,然后将报文段传递到网络层,被称为多路复用。
运输层多路复用要求:
- 套接字有唯一标识符。
- 每个报文段有特殊字段指示该报文段要交付到的套接字。
特殊字段是源端口号字段和目的端口号字段。端口号是16比特数,大小在0~65535之间;0~1024是周知端口号,限制使用。
无连接的多路复用与多路分解
一个UDP套接字是由一个二元组全面标识的。该二元组包含一个目的IP地址和一个目的端口号。那么对UDP来说,源端口号有什么用呢?
在A到B的报文段中,源端口号用作”返回地址“的一部分,即当B需要回发一个报文段给A时,B到A的报文段中的目的端口号便从A到B的报文段中的源端口号中取值。
两个具有不同源IP地址和源端口号的报文段,只要有相同的目的IP地址和目的端口号,就会被定向到同一个套接字。
面向连接的多路复用与多路分解
TCP套接字是由一个四元组(源IP地址,源端口号,目的IP地址,目的端口号)来标识的。
与UDP不同,两个具有不同源IP地址或源端口号的TCP报文段将被定向到两个不同的套接字。
Web服务器与TCP
现代高性能Web服务器通常只是用一个进程,但是为每个新的客户连接创建一个具有新连接套接字的新线程。
3.3 无连接运输:UDP
如果应用程序开发人员选用UDP而不是TCP,那么应用程序差不多就是直接与IP打交道。UDP从应用进程得到数据,副驾上用于多路复用、分解的源和目的端口号字段,以及两个其他的小字段,将形成的报文交给网络层。
使用UDP的原因
- 关于发送什么数据以及合适发送的应用层控制更为精细。采用UDP时,只要应用进程将数据传递给UDP,UDP就会将此数据打包进UDP报文段并立即传递给网络层。
- 无须连接建立。TCP在开始传输数据之前需要经过三次握手。UDP不需要任何准备。
- 无连接状态。TCP需要在端系统中维护连接状态,包括接收和发送缓存、拥塞控制参数以及序号与确认号的参数。UDP不维护连接状态们也不跟踪参数。
- 分组首部开销小。每个TCP报文段有20字节的首部开销,而UDP只有8字节的开销。
UDP报文段结构
3.4 可靠数据传输原理
看书….不太好记
3.5 面向连接的运输:TCP
三次握手:客户首先发送一个特殊的TCP报文段,服务器用另一个特殊的TCP报文段来响应,最后客户再用第三个特殊的报文段作为响应。
TCP连接建立后,客户进程通过套接字传递数据流,TCP将数据引导到该连接的发送缓存。
TCP为每块客户数据配上一个TCP首部,从而形成多个TCP报文段。下传到网络层后,将其分别封装在IP数据报中。
TCP报文段结构
首部包括源端口号和目的端口号,用于多路复用、分解。
还包括以下字段:
- 32比特的序号字段和32比特的确认号字段
- 16比特的接收窗口字段,用于流量控制。表示接收方愿意接受的字节数量
- 4比特的首部长度字段
- 可选与变长的选项字段,用于发送方和接收方协商最大报文段长度(MSS)。
- 6比特的标志字段。ACK比特用于指示确认字段中的值是有效的。
确认号就是主机等待的数据的下一个字节序号。
往返时间的估计与超时
TCP采用超时重传机制来处理报文段丢失问题。
如何设计超时间隔长度:
1.估计往返时间
某一时刻发送一个报文段的样本,获得SampleRTT值。由于路由器的拥塞和端系统负载的变化,SampleRTT会一直变化,所以TCP维持一个SampleRTT的均值:EstimatedRTT。一旦获得一个新的SampleRTT时,更新:
另外还要测量RTT的变化,RTT偏差:DevRTT,用于估算SampleRTT一般偏离EstimatedRTT的程度:
2.设置和管理重传超时间隔
超时间隔应大于等于EstimatedRTT,否则将造成不必要的重传。所以将超时间隔设置为EstimatedRTT加上一定余量。当SampleRTT波动较大时,余量大些;反之小些。
可靠数据传输
TCP的可靠传输服务确保一个进程从其接收缓存中独处的数据流是无损坏、无间隙、非冗余和按序的。
- 超时间隔加倍
当每次超时事件发生时,TCP重传具有最小序号的还未被确认的报文段。只是每次TCP重传时,都会将下一次超时间隔设置为先前值的两倍,而不再依靠EstimatedRTT和DevRTT。
- 快速重传
超时触发的重传的问题是超时周期可能相对较长,要等很久才会重传,增加了端到端时延。
发送方可以注意冗余ACK来检测到丢包:再次确认某个报文段中的ACK,而发送方先前已经收到对该报文段的确认。
由于TCP采用的是累计确认机制,即当接收端收到比期望序号大的报文段时,便会重复发送最近一次确认的报文段的确认信号,我们称之为冗余ACK。
如图所示,报文段1成功接收并被确认ACK2,接收端的期待序号为2,当报文段2丢失,报文段3失序到来,与接收端的期望不匹配,接收端重复发送冗余ACK2。
如果在超时重传定时器溢出之前,接收到连续的三个重复冗余ACK(其实是收到4个同样的ACK,第一个是正常的,后三个才是冗余的),发送端便知晓哪个报文段在传输过程中丢失了,于是重发该报文段,不需要等待超时重传定时器溢出,大大提高了效率。这便是快速重传机制。
为什么是三个冗余ACK:
即使发送端是按序发送,由于TCP包是封装在IP包内,IP包在传输时是乱序的,所以TCP包到达接收端也是乱序的。乱序也会造成冗余ACK,因此就需要斟酌发送出来的冗余ACK是由于丢包还是由于乱序发送。所以把三次容易ACK作为判定丢失的基本准则:
可以看到三次冗余ACK作为阈值比较合理。
流量控制
一条TCP连接的每一侧主机都为该连接设置了接收缓存。当该TCP接收到正确、按序的字节后,就放入接收缓存。相关的应用进程会从缓存中读取数据,而不是数据刚一到达就立刻读取。
TCP为应用进程提供了流量控制服务,消除发送方使接收方缓存溢出的可能。因此也是一个速度匹配服务。
TCP让发送方维护一个接收窗口的变量来提供流量控制,用于给发送方指示该接收方还有多少可用的缓存空间。
TCP连接管理
TCP建立连接方式(三次握手):
- 客户端TCP向服务端TCP发送一个特殊的TCP报文段,不包含应用层数据报文,但是在首部中的一个标志位(SYN)被置为1。因此它也被称为SYN报文段。另外,客户随机选择一个初始序号(
client_isn
),放在该起始的SYN报文段的序号字段中。 - 当SYN报文段到达服务器,服务器为该TCP连接分配TCP缓存和变量,并向客户TCP发送允许连接的报文段。这个允许连接的报文段也不包含应用层数据。但在首部包含3个重要信息:①SYN比特被置为1;②该TCP报文段首部的确认号字段被置为
client_isn+1
;③服务器选择自己的初始序号(server_isn
)并放到TCP报文段首部的序号字段中。这条允许连接的报文段被称为SYNACK报文段。 - 在收到SYNACK报文段后,客户也要给连接分配缓存和变量。客户主机则向服务器发送另外一个报文段;这最后一个报文段对服务器的允许连接报文进行确认(该客户通过ACK server_isn+1来确认)。因为连接已经建立,所以SYN比特被置为0。这次为三次握手的第三个阶段,可以在报文段中携带客户到服务器的数据。
连接结束:
参与TCP连接的两个进程中的任何一个都能终止该连接,连接结束后主机中的缓存和变量将被释放。
如果客户进程发出关闭连接命令,会引起客户TCP向服务器进程发送一个首部中一个标志位FIN被置为1的特殊报文段。服务器接收后,回送一个确认报文段。随后服务器发送它自己的终止报文段,其FIN比特被置为1。最后客户对这个服务器的终止报文段确认。最终所有资源被释放。
在一个TCP连接的生命周期内,客户TCP的状态图:
服务器端的TCP的状态图:
3.6 拥塞控制原理
分组重传时网络拥塞的征兆,但是无法处理导致网络拥塞的原因,因此需要在网络拥塞时遏制发送方的机制。
拥塞原因与代价
- 当分组的到达速率接近链路容量时,分组经历巨大的排队时延。
- 发送方必须执行重传以补偿因为缓存溢出而丢弃的分组。
- 发送方在遇到大时延时,会进行不必要重传导致路由器李永奇链路带宽来转发不必要的分组副本。
- 当一个分组沿一条路径被丢弃时,每个上游路由器用于转发该分组的传输容量就浪费了。
3.7 TCP拥塞控制
TCP必须使用端到端拥塞控制,而不是网络辅助的拥塞控制,因为IP层不向端系统提供显式地网络拥塞反馈。
TCP让每一个发送方根据所感知到的网络拥塞程度来限制其能向连接发送流量的速率。
TCP如何限制其向连接发送流量:
TCP连接的每一端都由一个接收缓存、一个发送缓存和几个变量组成。运行在发送方的TCP拥塞控制机制跟踪一个额外的变量:拥塞窗口(cwnd),它限制TCP发送方能向网络中发送流量的速率。
通过调节cwnd的值,发送方能够调整发送数据的速率。
TCP发送方如何感知路径上的拥塞:
当出现过度拥塞时,在这条路径上的路由器会缓存溢出,造成丢弃数据报。丢弃的数据报会引起发送发的丢包(或超时或收到三个冗余ACK),那么发送方就认为在路径上出现了拥塞。
TCP使用确认(ACK)来调整拥塞窗口长度,根据ACK到来的速率。所以TCP被说成自计时。
TCP使用下列原则:
- 一个丢失的报文段表意味着拥塞,因此当出现丢失报文段时应该降低TCP发送方的速率
- 一个确认报文段表示该网络正在向接收方交付发送方的报文段。因此对先前未确认报文段的确认到达时,增加发送方速率
- 带宽探测。TCP发送方增加传输速率,从该速率后退进而再次开始探测,看看拥塞开始速率是否发生变化
TCP拥塞控制算法
①慢启动
当一条TCP连接开始时,cwnd值通常初始化为一个MSS的较小值。TCP发送方希望迅速找到可用带宽的数量。在慢启动状态,cwnd的值以一个MSS开始并且每当传输的报文段首次被确认就增加一个MSS。
这一过程每过一个RTT,发送速率就翻倍,虽然起始慢,但是在发送阶段指数增长。一旦出现超时的丢包事件,TCP发送方就将cwnd设为1并重新开始慢启动过程,并且将第二个状态变量ssthresh设置为cwnd/2。当检测到cwnd==ssthresh时,TCP结束慢启动,转移到拥塞避免模式。
②拥塞避免
进入拥塞避免状态后,cwnd的值大约是上次遇到拥塞时的一半。所以不再每过一个RTT就翻一倍,而是只增加一个MSS。
当出现丢包情况,将ssthresh设置为cwnd的一半,并将cwnd设置为1;进入快速恢复模式。
③快速恢复
在快速恢复中,对于引起TCP进入该状态的缺失报文段,对收到的每个冗余ACK,cwnd增加一个MSS。当对丢失报文段的一个ACK到达时,TCP在降低cwnd后进入拥塞避免状态。如果出现超时事件,快速恢复执行上述两个模式的相同动作后,进入慢启动状态;当丢包事件出现,ssthress为cwnd的一半,cwnd设为1个MSS。