传输层的任务

传输层的协议为应用进程提供端到端的通信服务,它提供面向连接的数据流支持、可靠性、流量控制、多路复用等服务

该层的协议大多是 客户端/服务端(C/S) 形式,客户端发起请求,服务端提供服务处理请求;在UNIX系统中服务端程序叫守护进程,通过端口号识别,如HTTP的守护进程是httpd,端口号为80,ssh的是sshd,端口号为22;系统中有一种超级守护进程inetd,它负责收到客户端请求以后用fork新建一个进程并用exec转换为对应的守护进程

两种代表性协议

  • TCP:面向连接的,可靠的流协议,主要用于必要实现可靠传输的情况,有一系列可靠性传输机制(见后文)
  • UDP:利用IP提供面向无连接的通信服务,用于对高速传输实时性有较高要求的通信或广播通信(即时通信),细节控制一般交给上层的应用程序处理

流:不间断的数据结构

TCP:Transmission Control Protocol

UDP:User Datagram Protocol

通常操作系统会提供socket的API,程序可以通过socket设置对端ip地址、端口号实现数据的发送与接收

端口号

类似于数据链路和IP中的地址,在传输层用端口号来识别同一台计算机中进行通信的不同应用程序(也叫程序地址)

识别一个通信的5个信息:源IP、目标IP、协议号、源端口号、目标端口号

端口号的确定有两种方法:

  • 标准既定(静态),应用程序有指定的端口号(知名端口号)
  • 时序分配(动态),交给操作系统分配

需要注意的是,不同的传输协议可以使用相同的端口号,因为端口号由其使用的传输层协议决定的

TCP的控制机制

和UDP不同,TCP的控制欲很强,它要传输过程中确保可靠性,要处理各类会发生和可能发生的情况,主要一些机制有序列号、校验和、确认应答、重发控制、连接管理以及窗口控制等

确认应答

TCP中当发送端的数据到达接收端时,接收端主机会返回一个已收到消息的通知,这个消息就是确认应答(ACK)

ACK:Positive Acknowledgement

如果在一定时间没有等到ACK,发送端会认为数据已丢失并进行重发处理,例如对方收到数据但返回的ACK在途中丢失,数据在传输过程中丢失,其他网络原因导致的延迟到达;为了减少这些情况带来的流量浪费,需要一种机制来识别是否已接收数据以及判断是否需要接受数据,它就是序列号 tcp-ack.jpg 序列号是按顺序给发送数据的每一个字节都标上号码的编号,接收端接收到TCP首部中的序列号和数据长度,将下一个要接收的序号作为ACK返回给发送端

光有序列号还不够,还要考虑到未收到ACK的情况,这时候就用重发超时来辅助,它是在重发数据之前,等待确认应答到来的那个特定时间间隔,这个时间相对每次发包时计算的往返时间(RTT)及偏差值的和再稍大一点

RTT:Round Trip Time,报文段的往返时间

偏差:RTT时间波动的值、方差,也称抖动

在Unix和Windows系统里,除了最初的数据包(没计算往返时间,一般为6秒),重发超时至少是1秒(重发超时最小0.5+偏差最小0.5),重发了一定次数仍没有ACK返回,就会判断为网络或对端主机发生异常,强制关闭连接

连接

连接是指各种设备、线路或网络中进行通信的两个应用程序为了相互传递消息而专有的、虚拟的通信线路,也叫做虚拟电路

TCP通过首部发送一个SYN包作为建立连接的请求等待ACK,如果对端发来ACK则认为可以进行数据通信,此外在通信结束断开连接时也需要请求(FIN包)-应答(ACK)处理 tcp-7.jpg 建立一个TCP连接需要发送3个包,因此也叫三次握手,该过程中双方会协商发送数据包的大小(MSS),最终在两者之间选择较小值使用

MSS:Maximum Segment Size,最大消息长度。理想情况为 在IP中不会被分片处理的最大数据长度

窗口控制

如果每个数据包都要进行确认应答,网络的吞吐量会随着包的往返时间变长而变差,从而使得通信性能变低,针对这个问题TCP使用了窗口,它以更大的单位进行确认,从而大幅度缩短转发时间

窗口大小:无需等待确认应答而可以继续发送数据的最大值

tcp-window.jpg 在收到确认应答的情况下,将窗口移动到确认应答中的序列号的位置,这种机制也被称为滑动窗口控制,可以顺序将多个段同时发送以提高通信性能

窗口控制也有对应的重发机制

  • ACK未能返回:无需重发,数据已到达对端,可以通过下个ACK进行确认
  • 发送的数据中途丢失:针对丢失数据的序列号一直发送ACK,发送端接到3次ACK后会判定报文丢失并进行重发(也称高速重发控制)

流控制

为了防止发送端发送超过接收端能处理的数据范围而导致数据被丢弃的情况发生,TCP使用流控制让发送端根据接收端的实际接收能力来控制发送的数据量,通过接收端告知发送端自己的窗口大小,发送端主机会根据接收端主机的指示,对发送数据的量进行控制 tcp-stream.jpg

当接收端缓冲区满时窗口大小为0,当接收端回到可接收状态时会向发送端发送一个窗口更新通知,之后发送端继续发送数据,在等窗口更新通知的过程中发送端会不时发送窗口探测的包,由此可以避免接收端发送的窗口更新通知丢失而导致传输中断的情况

拥塞控制

在网络出现拥堵时,如果突然发送一个较大量的数据,可能会导致整个网络的瘫痪,所以需要在通信开始时对发送数据量进行控制

TCP通过拥塞窗口慢启动的算法来实现控制,表现为刚开始发送数据时将拥塞窗口大小设置为1MSS,随着每次收到ACK后拥塞窗口大小加1,发送时将拥塞窗口的大小与接收端主机通知的窗口大小进行比较并选择小值; tcp-congest.jpg 为了防止拥塞窗口指数级增加,引入了慢启动阀值,在超出阀值的情况下只允许以下比例放大窗口:

1个数据段的字节数/拥塞窗口(字节) × 1个数据段的字节数

TCP通信开始之后网络吞吐量会逐渐上升,随着网络拥堵吞吐量也会极速下降,然后再进入逐渐上升的阶段,感觉像在逐步占领网络带宽

提高网络利用率

有一些算法和机制:

  • Nagle算法:延迟发送发送端剩余的较小数据,利用率会提高,但会有一定程度延迟
  • 延迟确认应答:收到数据后并不立刻返回ACK,通常每两个数据段返回一次ACK
  • 捎带应答:ACK和回执数据通过一个包发送,需要启用延迟确认应答的基础上