一、SCTP介绍
SCTP是流控制传输协议(Stream Control Transmission Protocol)。SCTP和TCP比较像,提供可靠性、排序、流量控制以及全双工的数据传送。我们SCTP中使用“关联”一词取代“连接”是为了避免这样的内涵: 一个连接只涉及两个IP地址之间的通信。一个关联指代两个系统之间的一次通信,它可能因为SCTP支持多宿而涉及不止两个地址。
1 面向连接
SCTP是面向消息的(message oriented)。它提供各个记录的按序递送服务。与UDP一样,由发送端写入的每条记录的长度随数据一道传递给接收端应用。
SCTP能够在所连接的端点之间提供多个流,每个流各自可靠地按序递送消息。一个流上某个消息的丢失不会阻塞同一关联其他流上消息的投递。这种做法与TCP正好相反,就TCP而言,在单一字节流中任何位置的字节丢失都将阻塞该连接上其后所有数据的递送,直到该丢失被修复为止。
2 多宿特性
SCTP还提供多宿特性,使得单个SCTP端点能够支持多个IP地址。该特性可以增强应对网络故障的健壮性。
二、SCTP连接的建立和终止
1 四路握手
- 客户SCTP发送一个INIT消息(初始化),该消息告诉服务器客户的IP地址清单、初始序列号、用于标识本关联中所有分组的起始标记、客户请求的外出流的数目以及客户能够支持的外来流的数目。
- 服务器以一个INIT ACK消息确认客户的INIT消息,其中含有服务器的IP地址清单、初始序列号、起始标记、服务器请求的外出流的数目、服务器能够支持的外来流的数目以及一个状态cookie。状态cookie包含服务器用于确信本关联有效所需的所有状态,它是数字化签名过的,以确保其有效性。
- 客户以一个COOKIE ECHO消息回射服务器的状态cookie.除COOKIE ECHO外,该消息可能在同一个分组中还捆绑了用户数据。
- 服务器以- -个COOKIE ACK消息确认客户回射的cookie是正确的,本关联于是建立。该消息也可能在同一个分组中还捆绑了用户数据。
2 三次挥手
SCTP不像TCP那样允许“半关闭”的关联。当一端关闭某个关联时, 另一端必须停止发送新的数据。关联关闭请求的接收端发送完已经排队的数据(如果有的话)后,完成关联的关闭。上图展示了这一交换过程。
SCTP没有类似于TCP的TIME_ WAIT状态,因为SCTP使用了验证标记。所有后续块都在捆绑它们的SCTP分组的公共首部标记了初始的INIT块和INIT ACK块中作为起始标记交换的验证标记; 由来自旧连接的块通过所在SCTP分组的公共首部间接携带的验证标记对于新连接来说是不正确的。因此,SCTP通过放置验证标记值就避免了TCP在TIME_WAIT状态保持整个连接的做法。
3 SCTP分组交换
4 SCTP状态图
![](https://i-blog.csdnimg.cn/blog_migrate/84331b0606822fa25af1336eb7130cf9.png)
三、SCTP的益处
SCTP的益处如下:
(1) SCTP直接支持多宿。一个端点可以利用它的多个直接连接的网络获得额外的可靠性。除了移植到SCTP外,应用程序无需采取其他行为就可以自动使用SCTP的多宿服务。
(2)可以消除头端阻塞。应用进程可以使用单个SCTP关联并行地传输多个数据元素。同一个关联内,一个流中的数据丢失不会影响其他并行的流中的数据流动。
(3)保持应用层消息边界。许多应用发送的并不是字节流,而是消息。SCTP保持应用进程: 发送的消息边界,从而略微简化了应用程序开发人员的任务。使用SCTP无需在字节流中标记消息边界,也无需提供在接收端从字节流中重构出消息的特殊处理代码。
(4)提供无序消息服务。对于某些应用,消息的到达顺序无关紧要。这样的应用出于可靠性要求一般使用TCP,不过没有顺序要求的消息还是将按照发送端提交顺序递送到接收端。其中任何- -个消息的丢失将导致并非不可避免的头端阻塞,即后续消息即使到达也不能提前无序递送。SCTP的无序服务可用于避免这个问题,使得应用需求与传输服务直接匹配。
(5)有些SCTP实现提供部分可靠服务。这个特性允许SCTP发送端为每个消息指定一个生命期,使用的是sctp_ sndrcvinfo结构的sinfo_ timetolive字段。(这个生命期不同于IPv4的TTL或IPv6的跳限,它是真正的时间长度.)当源端点和目的端点都支持本特性时,时间敏感的过期数据可改由传输层而不是应用进程丢弃(该数据可能发送过,不过丢失了),从而在面临网络阻塞时优化数据的传输。
(6) SCTP以一到一式接口提供了从TCP到SCTP的简易移植手段。该接口类似典型的TCP接口,因此稍加修改,一个TCP应用程序就能移植成SCTP应用程序。
(7) SCTP提供TCP的许多特性,包括正面确认、重传丢失数据、重排数据、窗口式流量控制、慢启动、拥塞避免、选择性确认,没有包括进来的两个例外特性是半关闭状态和紧急数据。
(8) SCTP提供许多供应用进程配置和调整传输服务,以便基于关联匹配其需求的挂钩。这些挂钩提供的灵活性配合良好的默认设置(供不希望调整传输服务的应用进程使用),为应用程序提供了TCP难以企及的控制能力。
SCTP不提供的TCP特性:
(1) 半关闭状态。当一个应用进程关闭了某个TCP连接的自身一半却仍然允许对端发送数据时,该连接进入半关闭状态(6.6节), 同时告知对端本端已经发送完数据。使用本特性的应用不是很多,因此在SCTP开发阶段,本特性被认为不值得增加到SCTP中。确实需要本特性的应用程序移植到SCTP时不得不修改应用层协议,在应用数据流中提供这个告知EOF的手段。有些个案如此修改协议并非轻而易举之事。
(2) 紧急数据。使用分离的SCTP流传输紧急数据多少类似TCP的紧急数据的语义,不过难以准确复制这个特性。
不能从SCTP中真正获益的是那些确实必须使用面向字节流传输服务的应用,譬如说telnet、rlogin、 rsh、 ssh等等。 对于这样的应用,TCP能够比SCTP更高效地把字节流分割分装到TCP分节中。SCTP忠实地保持消息边界,当每个消息的长度仅仅是一个字节时,SCTP封装消息到数据块中的效率非常之低,导致过多的开销。
四、SCTP协议
一个SCTP分组含了一个公共的分组头(Common Header)和若干数据块(Chunk),每个数据块中既可以包含控制信息,也可以包含用户数据。
除了INIT、INIT ACK和SHUTDOWN COMPLETE数据块外,其他类型的多个数据块可以捆绑在一个SCTP分组中,以满足对MTU大小的要求。当然,这些数据块也可以不与其他数据块捆绑在一个分组中。如果一个用户消息不能放在一个SCTP分组中,这个消息可以被分成若干个数据块 [1] 。
-
Source Port Number:16比特的无符号整数,源端口号,识别SCTP发送端点的SCTP端口号。接收方可以使用源端口号、源IP地址、目的端口号和目的IP地址标识该SCTP分组所属的偶联。
-
Destination Port Number:16比特的无符号整数,目的端口号,为目的端点的SCTP端口号。接收主机可以使用目的端口号将SCTP分组复用到正确的端点或应用中。
-
Verification Tag:32比特的无符号整数,验证标签是偶联建立时,本端端点为这个偶联生成一个随机标识。偶联建立过程中,双方会交换这个TAG,到了数据传递时,发送端必须在公共分组头中带上对端的这个TAG,以备校验。包含INIT数据块的分组中验证标签必须为0。在包含SHUTDOWN-COMPLETE数据块且设置了T比特的分组中,验证标签必须要从包含 SHUTDOWN-ACK数据块的分组中复制。
在包含ABORT数据块的分组中,验证标签必须要从触发这个ABORT发送的分组中复制。
-
Checksum:32比特的无符号整数,SCTP通过对用户数据使用ADLER-32算法,计算出一个32位的校验码,带在数据报中,在接收端进行同样的运算,通过检查校验码是否相等来验证用户数据是否遭到破坏。
-
Chunk Type:8比特的无符号整数,块类型定义在块值(Chunk Value)中消息所属的类型。包括:INIT、INIT ACK、SACK、ABORT、ERROR、SHUTDOWN、COOKIE ACK等13种数据块类型。该参数的取值范围为0~254,255留作今后的扩展。数据块类型字段的编码分配如下:
0:净荷数据(DATA)
1:启动(INIT)
2:启动证实 (INIT ACK)
3:选择证实 (SACK)
4:Heartbeat请求(HEARTBEAT)
5:Heartbeat证实(HEARTBEAT ACK)
6:中止 (ABORT)
7:关闭(SHUTDOWN)
8:关闭证实(SHUTDOWN ACK)
9:操作差错(ERROR)
10:状态Cookie(COOKIE ECHO)
11:Cookie证实(COOKIE ACK)
12:为明确拥塞通知响应(ECNE)预留
13:为降低拥塞窗口(CWR)预留
14:关闭完成(SHUTDOWN COMPLETE)
15~62:IETF预留
63:IETF定义的数据块扩展
64~126:IETF预留
127:IETF定义的数据块扩展
128~190:IETF预留
191:IETF定义的数据块扩展
192~254:IETF预留
255:IETF定义的数据块扩展
Chunk type的高两位bit指示了收端不认识对应的chunk type的处理原则:
00:停止处理数据报并丢弃,不再处理报中的其他Chunk。
01:与00相同处理外,还要在ERROR或INIT ACK中上报,原因为不认识的参数类型。
10:忽略该Chunk ,继续处理数据报中的其他Chunk。
11:同10相同处理外,还要在ERROR中上报,原因为不认识的Chunk类型。
-
Chunk Flags:8比特的无符号整数,块标志位用法由块类型决定。除非被置为其他值,块标记在传送过程中会被置0而且接收端点会忽视块标记。
-
Chunk Length:16比特的无符号整数,块长度用来表示包括块类型、块标记、块长度和块值在内的字节数,长度使用二进制表示。
-
Chunk Value:变长,块值字段是在该数据块中真正传送的信息,内容由数据块类型决定。块值的长度为不定长。