运输层
5.1 运输层概述
运输层的主要任务是,如何为运行在不同主机上的应用进程提供直接的通信服务。运输层协议又称为端到端协议。
根据应用需求的不同,因特网的运输层为应用层提供了两种不同的运输协议,即面向连接的TCP和无连接的UDP
5.2 运输层端口号、复用与分用的概念
端口号
运行在计算机上的进程使用进程标识符PID
来标志。但是因特网上的计算机并不是使用统一操作系统,不同的操作系统(windows,linus,Mac OS)又使用不同格式的进程标识符
。为了使运行不同操作系统的计算机的应用程序之间能够进行网络通信,就必须使用统一的方法对TCP/IP体系的应用进程进行标识
。
TCP/IP体系的运输层使用端口号
来区分应用层的不同应用进程。
端口号使用16比特标识,取值范围0~65535
- 熟知端口号:0~1023,IANA把这些端口号指派给了TCP/IP体系中最重要的一些应用协议,例如:FTP使用21/20,HTTP使用80,DNS使用53。
- 登记端口号:1024~49151,为没有熟知端口号的应用程序使用。使用这类端口号必须在IANA按照规定的手续登记,以防止重复。例如:MySQL 使用的端口是 3306。
- 短暂端口号:49152~65535,留给客户进程选择暂时使用。当服务器进程收到客户进程的报文时,就知道了客户进程所使用的动态端口号。通信结束后,这个端口号可供其他客户进程以后使用。
端口号只具有本地意义 ,即端口号只是为了标识本计算机应用层中的各进程 ,在因特网中,不同计算机中的相同端口号是没有联系的
发送方的复用和接收方的分用
发送方的某些应用进程所发送的不同应用报文,在运输层使用UDP协议进行封装,这称为UDP复用 。而另一些应用进程所发送的不同应用报文,在运输层使用TCP协议进程封装,则被称为TCP复用。
运输层采用端口号区分不同的应用进程,不管是使用运输层UDP协议封装成的UDP用户数据报,还是使用TCP协议封装成的TCP报文段,在网络层都需要被IP协议封装成IP数据报,这被称为IP复用。
IP数据报首部中协议字段的值用来表名IP数据报的数据载荷部分封装的是何种协议数据单元。
- 取值为6,表示封装的是TCP报文段
- 取值为17,表示封装的UDP报文段
接收方的网络层收到IP数据报后进行IP分用 。若IP数据报首部中协议字段的值为17,则把IP数据报的数据载荷部分所封装的UDP用户数据报上交运输层的UDP。若协议的字段为6,则把IP数据报的数据载荷部分所封装的TCP用户数据报上交运输层的TCP。运输层对UDP用户数据报进行UDP分用 ,对TCP报文进行TCP分用。根据端口号将它们交给上层相应的应用进程。
5.3 UDP 和 TCP 的对比
5.4 TCP 的流量控制
一般来说,我们总是希望数据传输得更快一些。但如果发送方把数据发送得过快,接收方就可能来不及接收,这就会造成数据的丢失。所谓流量控制
(flowcontrol)就是让发送方的发送速率不要太快,要让接收方来得及接收 。利用滑动窗口机制
可以很方便地在TCP连接上实现对发送方的流量控制。
TCP接收方 利用自己的接收窗口的大小来限制发送方发送窗口的大小。
TCP发送方 收到接收方的零窗口通知 后,应启动持续计时器 。持续计时器超时后,向接收方发送零窗口探测报文。
- ACK: TCP报文段首部中的标志位,取值1表示这是一个TCP确认报文段。
- ack: TCP报文段首部中的确认号字段,取值201表示序号201之前的数据已全部正确接收,现在希望收到序号201及其后续数据。
- rwnd:是TCP报文段首部中的窗口字段,取值300表示自己的接收窗口大小为300
假设主机B向主机A发送了零窗口的报文段后不久,主机B的接收缓存又有了一些存储空间。于是主机B向主机A发送了接收窗口等于300的报文段。然而这个报文段在传输过程中丢失了。
主机A一直等待主机B发送的非零窗口的通知。
主机B也一直等待主机A发送的数据。
如果不采取措施,这种互相等待而形成的死锁局面将一直持续下去。
为了解决这个问题,TCP为每一个连接设有一个持续计时器,只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器超时,就发送一个零窗口探测报文,仅携带一字节的数据。而对方在确认这个探测报文段时,给出自己现在的接收窗口值,如果接收窗口值仍为0,那么收到这个报文段的乙方就重新启动持续计时器。
如果接收窗口不是0,那么死锁的局面就可以被打破。
5.5 TCP 的拥塞控制
在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏 。这种情况就叫做拥塞 。若出现拥塞而不进行控制,整个网络的吞吐量将随输入负荷的增大而下降。
慢开始
拥塞窗口在小于慢开始门限值时按照指数增加
拥塞避免
拥塞窗口在大于慢开始门限后每次加一,如果出现丢失,慢开始门限折半,拥塞窗口大小变为1。重新进行慢开始
快重传
快恢复
5.6 TCP 超时时间重传的选择
RTT:往返时间
RTO:超时重传时间
5.7 TCP 可靠传输的实现
TCP基于以字节为单位的滑动窗口来实现可靠传输
- 发送方在未收到接收方的确定时,可将发送窗口内还未发送的数据全部发送出去。
- 接收方只能接收序号落入发送窗口内的数据
虽然发送方的发送窗口是根据接收方的接收窗口设置的,但在同一时刻,发送方的接收窗口和接收方的接收窗口并不总是一样大
。
- 网络传送窗口值需要经历一定的时间滞后,并且这个时间还是不确定的。
- 发送方还可能根据网络当时的拥塞情况适当减小自己的发送窗口尺寸。
对于不按时序到达的数据应该如何处理
,TCP并无明确规定。
- 如果接收方把不按时序到达的数据一律丢弃,那么接收窗口的管理将会比较简单,但这样做对网络资源的利用不利,因为发送方会重复传送较多数据。
- TCP通常对不按时序到达的数据是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再
按时序交付上层的应用程序
。
TCP要求接收方必须有累计确认和捎带确认机制
,这样可以减小传输开销。接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息顺便捎带上。
接收方不应该过分推迟发送确认
,否则会导致发送方不必要的超时重创,这反而浪费了网络的资源。TCP标准规定,推迟延迟的时间不应超过0.5秒。若收到一连串具有最大长度的报文段,则必须每隔一个报文段就发送一个确认。- 捎带确认实际上并不经常发生,因为大多数应用程序很少同时在两个方向上发送数据
TCP的通信是全双工通信
。通信中的每一方都在发送和接收报文段。因此,每一方都有自己的发送窗口和接收窗口。
5.8 TCP 的运输连接管理
TCP是面向连接的协议,它基于运输连接来传送TCP报文段。
TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程。
TCP运输连接有以下三个阶段:
建立TCP连接
数据数据传输
释放连接
TCP的运输连接管理就是使运输连接的建立和释放都能正常地进行。
5.8.1 TCP 的连接建立
TCP的连接建立要解决以下三个问题:
- 使TCP双方能够确知对面的存在
- 使TCP双方能够协商一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选择以及服务等)
- 使TCP双方能够运输实体资源(如缓存大小、连接表中的项目等)进行分配
TCP报文中的字段
SYN:首部中的同步位
ACK:首部中的确认位
ack:确认号字段,主机甲对主机乙中TCP客户进程所选择的序列号seq的确认
seq:主机对另一个主机中TCP服务进程所选择的初始序号,可由TCP服务器随意制定
三次握手
-
TCP客户端进程向服务端进程发送TCP请求报文段。
-
当TCP服务端收到请求报文后,若同意连接,则向TCP客户端进程发送TCP连接请求确认报文段,并进入同步接收状态。
-
TCP客户进程收到TCP连接请求确认报文段后,还要向TCP服务端进程发送一个普通的TCP确认报文段,并进入连接已建立状态。
-
当TCP服务端收到报文段后也进入连接已建立状态,至此连接建立。
采用三报文握手而不是二报文握手的目的是为了防止已失效的连接请求报文段突然又传送到了TCP服务器
5.8.2 TCP 的连接释放
TCP的四次挥手
- TCP客户进程发送TCP连接释放报文段,并进入终止等待1状态
- TCP服务端收到TCP连接释放报文段后,会发送一个普通的TCP确认报文段并进入关闭等待状态。TCP服务端进程这时应通知高层应用进程:TCP客户端进程要断开与自己的TCP连接。此时从TCP客户端到TCP服务端进程这个方向的连接就释放了,这时的TCP属于半关闭状态,从TCP服务端进程到TCP客户端进程这个方向的连接并未关闭。
- TCP客户端进程收到TCP确认报文字段后就进入终止等待2状态,等待TCP服务端进程发出的TCP连接释放报文段
- 若使用TCP服务器进程的应用程序已经没有数据要发送了,应用程序就通知其TCP服务端进程释放连接。TCP服务进程发送TCP连接释放报文段并进入最后确认状态
- TCP客户进程收到TCP连接释放报文段后,必须针对该报文段发送普通的TCP确认报文段。之后进入时间等待状态,经过2 MSL后才能进入关闭状态
- TCP服务端进程收到该报文段后就进入关闭状态
TCP保活计时器
TCP双方已经建立了连接,突然TCP客户端进程发生了故障,通过计时器,可以使TCP服务端进程发现这种状况。
5.9 TCP 报文的首部格式
为了实现可靠传输,TCP采用面向字节流的方式。但TCP在发送数据时,是从发送缓存取出一部分或全部字节并给其添加一个首部使之成为TCP报文段后进行发送。
- 一个TCP报文段由首部和数据载荷两部分构成;
- TCP的全部功能都体现在它首部中各字段的作用