6.5 其他传输层协议
实际上,UDP与TCP在很长的一段时间,霸占了“传输至尊榜”中的前两位,难以分出高下,但是仍有几款“神兵利器”,被收入兵器榜前十位,接下来就来介绍一些已经被提案且在今后可能会被广泛使用的传输层协议。
UDP-Lite(Lightweight User Datagram Protocol,轻量级用户数据报协议)
是一种用于扩展UDP技能的传输层协议。应对的情况是,基于UDP的通信中如果校验和出现错误,就会将所有包全部丢弃,但是有些应用(例如,对于我们做音视频的而言,有些编码数据即使被破坏了部分,也是可以使用的)在面对这种情况时,并不希望将所有已收到的包丢弃。
有一种方法是,不启用校验和,但是这并不是很好的方法,因为如果是UDP首部中的端口号被破坏或者IP首部的IP地址被破坏,就会导致严重后果。
所以,UDP-Lite应运而生,其本质与UDP几乎完全一样,区别在于计算校验和的范围可以由应用自行决定。该范围可以是“包+伪首部的校验和”的计算,也可以是“首部+伪首部的校验和”的计算,还可以是“首部+伪首部+数据从起始到中间某个位置的校验和”的计算。
后续我们会讲到,UDP首部中有个字段表示为包长,该值就决定了协议首部第一个字节到第多少个字节要进行校验和计算。
使用了此机制,就可以只检验那些决不允许发生错误的部分。对于其他内容,就可以睁一只眼闭一只眼了。
SCTP(Stream Control Transmission Protocol,流控制传输协议)
以下内容引用自百度词条“SCTP”:
在客户和服务器之间提供关联(association),并像TCP那样给应用提供可靠性、排序、流量控制以及全双工的数据传输。SCTP中使用“关联”一词替代“连接”是为了避免这样的内涵:一个连接只涉及两个IP地址间的通信。一个关联指代两个系统之间的一次通信,它可能因为SCTP支持多宿而涉及不止两个地址。
其有以下特点:
- 单位是消息(message)。在TCP中接收端并不知道发送端应用决定的消息大小(回顾一下,TCP中有约束发送端自身的拥塞控制,以及借由接收端告知发送端的流控制)
- 支持多个宿主,即使网络接口控制器(NIC)发生变化,也可以继续通信,相较于TCP提高了故障应对能力。
- 支持多数据流通信,TCP中建立多个连接才能实现通信的效果,在SCTP中一个连接就可以。
- 可以定义消息的生存期限,超过生存期限的消息不会被重发
该协议用于发送众多较小消息(又名数据块,chunk)的情况。多重宿主的意思,以笔记本为例,笔记本电脑既可以连接以太网,又可以连接无线LAN,这是NIC会获取不同的IP地址,即使中途发生以太网和无线LAN的切换,也可以保持通信不中断。
总的来说,SCTP可以给具备多个NIC的主机提供更可靠的传输。
DCCP(Datagram Congestion Control Protocol,数据报拥塞控制协议),辅助UDP,因为UDP中没有拥塞控制机制。所以当用UDP发送大量数据的时候,就很容易出现问题。
其特点如下:
- 不提供发送数据的可靠性传输
- 具备建立和断开连接的处理,在此方面具有可靠性
- 可根据网络拥堵情况进行拥塞控制,根据RFC4340,DCCP可以提供
类似TCP(TCP-Like)拥塞控制
和TCP友好升级控制(TCP-Friendly Rate Control)
- 使用了ACK机制,用于重发与否的判断
6.6 UDP首部的格式
此前的内容中一直或多或少的提到过UDP和TCP首部中的某些字段的作用,其就好比武林秘籍一般,死读书是很难有用处的,需要将其化为一种意向。(我的想法就是,想到该怎么用的时候,就查一查就好了)
以下就是老生常谈的每个字段的集体用处介绍:
-
源端口号 16bits
可以设置为0,表示没有源端口号,用于不需要返回的通信中
-
目标端口号 16bits
-
包长度 8bits
UDP首部的长度和数据的长度之和,单位为字节;
此前讲述UDP-Lite协议的时候,提到过该字段
-
校验和
这部分用于提供可靠的UDP首部和数据而设计(可能有人会问UDP不是不可靠的吗?确实如此,但是不能妨碍想要实现较为可靠的传输的应用对其进行处理)。UDP使用的是附加在首部之前的伪首部 + 首部 + 数据,用于计算校验和。
下图(来源于《计算机网络》一书)可以较为直观的了解具体是如何进行计算的
如上图所示,接收端收到UDP后,从IP首部知悉IP地址构造UDP伪首部,再进行校验和计算。校验和等于校验和字段以外部分的1的补码和。因此,包括校验和字段在内的所有数据之和结果为“16位全部是1”时,才会认为收到的数据是正确的。
UDP中也可以不使用校验和,此时在校验和字段中填入0。此时,协议处理开销会降低,数据转发速度会相应有所提高。
书中也提到了为什么要是用伪首部,归根到底原因还在于五元组多数情况下是不能出错的,UDP首部中仅有五元组中源端口与目标端口两元,如果其余三元在传输过程中出现问题,就极有可能导致要收包的应用收不到包,不该收包的却收到了。
另外,IP首部没有校验和字段,正是通过UDP的伪首部,实现了IP首部并不可靠的情况下仍可以提供可靠的通信传输。
6.7 TCP 首部格式
如下图所示,明显要比UDP复杂很多。
-
源端口号 16bits
-
目标端口号 16bits
-
序列号 32bits
用以表示“累积发送字节数”的值。该值不会从0或1开始,而是建立连接时,有系统生成的随机数作为初始值。
另外,连接和断开连接时发送的SYN与FIN包,虽然不携带数据,但是也会作为一个字节,增加相应的序列号的值。
-
确认应答号 32bits
下一次应该收到的数据的序列号。实际上指已收到确认应答号减一为止的数据,表示此前数据都已正常接收。
-
数据偏移 4bits
表示TCP传输的数据部分应该从TCP包的那个位开始计算,也可以把它看做是TCP的首部长度。例如,该字段设置为5,TCP首部长20字节,4x5 = 20,说明从TCP包的一开始到20字节为止都是TCP首部。
-
保留 4bits
用于扩展,一般设置为0。
-
控制位 8bits
该字段应该属于重中之重的内容了(因为内容多所以重)。其每一位的具体含义可以见下图(图中还包括数据偏移字段和保留字段)。
-
CWR = Congestion Window Reduced
与ECE位一同作用于IP首部的ECN字段;为1是表示通知对方已将拥塞窗口缩小。
-
ECE = ECN-Echo
该位置1时,表示通知对方,从对方到这边的网络有拥塞。
若在IP首部的ECN为1,则也会将TCP首部中的ECE设置为1.
-
URG = Urgent Flag
该位置1时,表示包中有需要紧急处理的数据。
-
ACK = Acknowledgement Flag
该位置1时,表示确认应答的字段有效。
TCP规定,除了起初建立连接的SYN包,该位必须置1.
-
PSH = Push Flag
该位置1时,表示需要将收到的数据立刻传给上层应用协议。
该位置0时,表示不需要立即传而是先进行缓存。
-
RST = Reset Flag
该位置1时,表示TCP中出现异常必须强制断开连接。
例如程序宕掉,主机电源断开等导致重启,从一个未被使用的端口发来通信等情况,所有用于连接的信息将被全部初始化。
-
SYN = Synchronize Flag
该位置1时,表示希望建立连接,并在序列号的字段中进行序列号初始值的设定。
-
FIN = Fin Flag
该位置1时,表示希望断开连接,今后不再有数据发送。值得注意的是,主机收到FIN包时,不必立即回复FIN包,而是可以等到缓冲区中的所有数据都已成功发送而被自动删除后再发。
-
-
窗口大小 16bits
用于通知相同TCP首部确认应答号所指位置开始,能够接受的数据大小。如果窗口为0,表示可以发送窗口探测,以了解最新的窗口大小,但这个数据必须是一个字节。
-
校验和
见下图
TCP校验和的计算方式与UDP相似,一样使用到了伪首部,一样使用到了填充0技巧,一样时通过二进制反码计算,区别在于其无法被关闭。
此处书中特意提了一下,为什么数据链路的FCS检验了噪声干扰带来的位错误,还需要在传输层再次进行校验和计算。其实,TCP与UDP的校验和更是一种进行路由器内存故障或程序漏洞导致的数据是否被破坏的检查。
-
紧急指针 16bits
仅有在URG控制位为1时有效,表示本报文段中紧急数据的指针。紧急数据为“从数据部分的首位到紧急指针所指示的位置为止”。
如何处理紧急数据则属于应用的问题。
-
选项
该字段用于提高TCP的传输性能。因为根据数据偏移进行控制,其长度最大为40字节。
选项字段尽量调整为32位的整数倍。书中列了一个表格,点出具有代表性的TCP选项。
其中重要的有MSS,窗口扩大,时间戳字段等。
本篇小结
这篇内容也是第六章的最后一篇,主要可以分为两部分
第一部分,对其他的一些传输层协议进行了简单介绍,包括UDP-Lite(制定校验和范围),SCTP(支持多宿主的系统性协议),DCCP(为UDP添加了拥塞控制机制)。
第二部分则对UDP和TCP首部进行了介绍,重点需要理解的内容应该是校验和的计算,其余内容在有困惑时查阅书籍即可。