从通信和信息处理的角度看,传输层是 5 层参考模型中的第 4 层,它向上面的应用层提供通信服务。它属于面向通信部分的最高层,同时也是用户功能中的最低层。
传输层为两台主机提供了应用进程之间的通信,又称为端到端通信。由于网络层协议是不可靠的,会使分组丢失、失序和重复等,所以派出传输层为数据传输提供可靠的服务。
既然传输层的UDP是不可靠的,为什么又说传输层提供可靠的服务?
确实传输层中的 UDP 是不可靠的,因为使用 UDP 不能保证数据报都能正确地到达目的地,UDP 发现错误之后可以选择丢弃,也可以选择向应用层报告错误。但是关键还是要由用户自己来选择,如果用户选择了 TCP(如 FTP 软件),自然传输层就是可靠的。但是,如果用户使用了 UDP(如 QQ 软件、视频会议软件等),传输层就不可靠。所以说传输层是否可靠与传输层使用的协议有很大关系,但是一般默认传输层是可靠的。
传输层的功能:
面向连接的服务还有以下两个功能:
在传输层应根据什么原则来确定使用面向连接服务还是无连接服务?
需要根据上层应用程序的性质来区分。例如,在传送文件时要使用文件传送协议 (FTP),而文件的传送必须是可靠的,不能有错误或者丢失,因此在传输层就必须使用面向连接的 TCP。但是若应用程序是要传送分组话音或视频点播信息,那么为了保证信息传输的实时性,传输层就必须使用无连接的 UDP。
应用进程看见的好像在两个传输层实体之间有一条端到端的逻辑通信信道,怎么理解?
TCP是面向连接的,但TCP 使用的IP却是无连接的。这两种协议都有哪些主要的区别?
TCP 是面向连接的,但TCP所使用的网络可以是面向连接的(如X.25网络,已经淘汰,在此仅作为例子,不用了解)也可以是无连接的(如现在大量使用的IP 网络)。选择无连接网络使得整个系统非常灵活,当然也带来了一些问题。
显然,TCP所提供的功能和服务要比 IP 所能提供的功能和服务多得多。这是因为 TCP使用了诸如确认、滑动窗口、计时器等机制,因而可以检测出有差错的报文、重复的报文和失序的报文。
前面讲过数据链路层按 MAC 地址寻址,网络层按IP 地址寻址,而传输层是按端口号寻址的。
端口(软件端口)就是传输层服务访问点,端口能够让应用层的各种应用进程将其数据通过端口向下交付给传输层以及让传输层知道应当将其报文段中的数据向上通过端口交付给应用层的相应进程。从这个意义上讲,端口就是用来标识应用层的进程。换句通俗的话,端口就类似于寝室号,而寝室里面住着应用进程。
由于同一时刻一台主机上会有大量的网络应用进程在运行,所以需要有大量的端口号来标识不同的进程。
端口用一个16位端口号进行标识,共允许有 216=65536个端口号。端口号只具有本地意义,即端口号只是为了标识本计算机应用层中的各进程。例如,主机A的8080号端口和主机B的8080号端口是没有任何联系的。
根据端口号范围可将端口分为3类:
登记端口:数值为1024~49151。它是为没有熟知端口号的应用程序使用的,使用这类端口号必须在IANA 登记,以防止重复。
客户端端口或短暂端口:数值为49152~65535。由于这类端口号仅在客户进程运行时才动态选择,所以称为短暂端口或临时端口。通信结束后,此端口就自动空闲出来,以供其他客户进程使用。
套接字:一台拥有IP 地址的主机可以提供许多服务,如 Web 服务、FTP 服务、SMTP 服务等,这些服务完全可以通过一个 IP 地址来实现。只有通过 IP 地址和端口号才能唯一确定一个连接的端口,称为套接字。
套接字=(主机IP地址,端口号)。它唯一地标识了网络中的某台主机上的某个应用进程。
传输层提供了两种类型的服务: 无连接服务和面向连接服务,相应的实现分别是用户数据报协议(UDP)和传输控制协议 (TCP)。
当采用 TCP 时,传输层向上提供的是一条全双工的可靠的逻辑信道;
当采用UDP 时,传输层向上提供的是一条不可靠的逻辑信道。
在网络传输层,TCP模块中有一个TCB(传输控制模块Transmit ControlBlock),它用于记录TCP运行过程中的变量。对于有多个连接的TCP,每个连接都有一个TCB。TCB结构的定义包括这个连接使用的源端口、目的端口、目的IP、序号、应答序号、对方窗口大小、自己窗口大小、TCP 状态等。
UDP和TCP 最大的区别在于它是无连接的,UDP 其实只在 IP 的数据报服务之上增加了端口的功能(为了找到进程)和差错检测的功能。
优点:
UDP 数据报有两个字段:数据字段和首部字段。首部字段有 8B,由4 个字段组成
UDP校验只提供差错检测。在计算校验和时,要在UDP 用户数据报之前临时加上 12B 的伪首部。
伪首部包括源 IP 地址字段、目的 IP 地址字段、全0字段、协议字段(UDP 固定为17)、UDP长度字段(图5-5 设用户数据的度是15B)。一定要记住首部只用于计算和验证校验和,其既不向下传送,也不向上递交。
按二进制反码计算后,当无差错时其结果应该为全 1;否则就表明有差错出现,接收方就应该丢弃这个UDP 报文。
两个数的二进制反码求和运算规则如下:
- 从低位到高位逐列进行运算。
- 0+0-0,0+1=1,1+1=0(进位1加到下一列)。
- 如果最高位相加产生进位,则需要对最后的结果加1。
TCP 的传输连接分为3个阶段:连接建立、数据传送和连接释放。TCP 传输连接的管理就是使传输连接的建立和释放都能正常地进行。
TCP把连接作为最基本的抽象,每一条TCP连接有两个端点,TCP 连接的端点不是主机不是主机的IP 地址,不是应用进程,也不是传输层的协议端口。TCP 连接的端点叫作套接字(Socket)或插口。端口号拼接到IP 地址即构成了套接字。
每一条 TCP 连接唯一地被通信两端的两个端点(两个套接字)所确定。例如,TCP 连接::={socket1,socket2}={(IP1:port1),(IP1:port2)}。
TCP的连接和建立都是采用客户/服务器方式(C/S)。主动发起连接建立的应用进程叫作客户(Client),被动等待连接建立的应用进程叫作服务器(Server)。
TCP传输连接的建立采用“三次握手”的方法:
采用“三次握手”的方法,目的是为了防止报文段在传输连接建立过程中出现差错。通过3次报文段的交互后,通信双方的进程之间就建立了一条传输连接,然后就可以用全双工的方式在该传输连接上正常地传输数据报文段了
TCP释放连接的过程:
数据传输结束后,通信双方都可释放连接。现在A 的应用进程先向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP 连接。A 将连接释放报文段首部的 FIN置1,其序号 seq=u,等待 B 的确认。这里要注意,因为 TCP 是双工的,也就是说,可以想象一对 TCP 连接上有两条数据通路。当发送 FIN 报文时,发送FIN 的一端就不能发送数据,也就是关闭了其中一条数据通路,但是对方还是可以发送数据的。
B 发出确认,确认号ack=u+1,而这个报文段自己的序号 seg=v。TCP 服务器进程通知高层应用进程。从A到B 这个方向的连接就释放了,TCP连接处于半关闭状态。B 若发送数据,则A 仍要接收。
TCP连接必须经过时间2MSL后才真正释放。
总结:
必须使得迟到的TCP 报文段的序号不处在新的连接所使用的序号范围之中这样,TCP在建立新的连接时所选择的初始序号一定要和前面的一些连接所使用过的序号不一样。因此,不同的 TCP 连接不能使用相同的初始序号。
TCP 是面向字节的。TCP将所要传送的报文看成是字节组成的数据流,并使每一个字节对应于一个序号。在连接建立时,双方要商定初始序号。TCP 每次发送的报文段的首部中的序号字段数值表示该报文段中的数据部分的第一个字节的序号。
TCP 的确认是对接收到的数据的最高序号表示确认。接收端返回的确认号是已收到的数据的最高序号加 1。因此,确认号表示接收端期望下次收到的数据中的第一个数据字节的序号。
TCP 每发送一个报文段,就对这个报文段设置一次计时器。只要计时器设置的重传时间到了规定时间还没有收到确认,那么就要重传该报文段。
TCP的一种自适应算法
记录每个报文段发出的时间以及收到相应的确认报文段的时间。这两个时间之差就是报文段的往返时延。
将各个报文段的往返时延样本加权平均,就得出报文段的平均往返时延(RTT)。
每测量到一个新的往返时延样本,就按下式重新计算一次平均往返时延。
RTT=(1-α)×(旧的 RTT)+α×(新的往返时延样本)
在上式中,0≤α<1。若 α 很接近于 1,表示新算出的平均往返时延 RTT 和原来的值相比变化较大,即 RTT 的值更新较快。若选择 α 接近于0则表示加权计算的 RTT 受新的往返时延样本的影响不大,即 RTT 的值更新较慢,一般推荐 α 取0.125。
计时器的超时重传时间(RTO)应略大于上面得出的 RTT,即
RTO=β×RTT(β>1)
Karn算法:报文段每重传一次,就把RTO增大一些。
新的 RTO=γ×(旧的RTO),γ系数的典型值是2。当不再发生报文段的重传时,才根据报文段的往返时延更新加权 RTT和 RTO的数值。
TCP可靠机制的体现
一般来说,人们总是希望数据传输得更快一些。但如果发送方把数据发送得过快,接收方就可能来不及接收,这就会造成数据的丢失。
流量控制 (Flow Control)就是让发送方的发送速率不要太快,既要让接收方来得及接收,也不要使网络发生拥塞。利用滑动窗口机制可以很方便地在TCP连接上实现流量控制。
在某段时间,若对网络中某资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏——产生拥塞。
出现资源拥塞的条件是:对资源需求的总和>可用资源
若网络中产生拥塞,网络的性能就要明显变坏,整个网络的吞吐量将随着输入负荷的增大而下降。
拥塞控制与流量控制的性质对比:
拥塞控制又分为闭环控制和开环控制
发送端的主机在确定发送报文段的速率时,既要根据接收端的接收能力,又要从全局考虑不要使网络发生拥塞。
TCP 要求发送端维护以下两个窗口:
发送端发送窗口的上限值应当取接收端窗口rwnd和拥塞窗口cwnd这两个变量中较小的一个,rwnd和cwnd 中较小的一个控制发送方发送数据的速率。
发送窗口的上限值=Min[rwnd,cwnd]
接收窗口的大小可以根据 TCP 报文首部的窗口字段通知发送端,而发送端怎么去维护拥塞窗口呢?
使用慢开始算法后,每经过一个传输轮次,拥塞窗口cwnd就加倍,即cwnd的大小呈指数形式增长。这样慢开始一直把拥塞窗口 cwnd 增大到一个规定的慢开始门限ssthresh(阙值),然后改用拥塞避免算法(一个传输轮次所经历的时间其实就是往返时间RTT。例如,拥塞窗口cwnd=4,这时的往返时间RTT就是发送方连续发送4个报文段并收到这4个报文段的确认总共经历的时间)。
为防止拥塞窗口cwnd 的增长引起网络阻塞,还需要一个状态变量,即慢开始门限ssthresh。
当 cwnd
当cwnd>ssthresh时,停止使用慢开始算法,改用拥塞避免算法。
当cwnd=ssthresh 时,既可以使用慢开始算法,也可以使用拥塞避免算法
拥塞避免算法的做法是:发送端的拥塞窗口 cwnd 每经过一个往返时延 RTT 就增加一个MSS的大小,通常表现为按线性规律增长。
无论在慢开始阶段,还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有按时收到确认),就要把慢开始门限 ssthresh 设置为出现拥塞时的发送窗口值的一半(但不能小于 2),然后把拥塞窗口 cwnd 重新设置为 1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。
发送端每收到一个确认,就把 cwnd 加1,于是发送端可以接着发送M1和M2两个报文段。
接收端共发回两个确认。发送端每收到一个对新报文段的确认,就把发送端的 cwnd加1。现在 cwnd从2增大到4,并可接着发送后面的4个报文段。
发送端每收到一个对新报文段的确认,就把发送端的拥塞窗口加1,因此拥塞窗口cwnd 随着传输轮次按指数规律增长。
总结:
首先要求接收方每收到一个失序的报文段后就立即发出重复确认。这样做可以让发送方及早知道有报文段没有到达接收方。发送方只要连续收到3个重复确认就应当立即重传对方尚未收到的报文段。
当发送端收到连续3个的重复的确认帧时,就执行“乘法减小”算法,把慢开始门限ssthresh设置为当前拥塞窗口的一半。但接下去不执行慢开始算法。
由于发送方现在认为网络很可能没有发生拥,所以现在不执行慢开始算法,即拥塞窗口 cwnd 现在不设置为1,而是将慢开始门限 ssthresh 设置为当前拥塞窗口的一半,然后开始执行拥塞避免算法(“加法增大”),使得拥塞窗口缓慢的线性增大。
快恢复算法具体如下: