SCTP 是在 IP 网络上使用的一种可靠的通用传输层协议。尽管 SCTP 协议最初是为发送电话信号而设计的(RFC 2960),但带来了一个意外的收获:它通过借鉴 UDP 的优点解决了 TCP 的某些局限。SCTP 提供的特性使套接字初始化的可用性、可靠性和安全性都得以提高。(图 1 给出了 IP 堆栈的层次化架构。)
图 1. IP 栈的层次化架构
本文简要介绍了 Linux 2.6 内核中 SCTP 的概念,重点介绍了一些高级特性(例如多宿主和多流),并且给出了服务器和客户机的部分代码片断(并给出了一个可以获得更多代码的 URL),从而展示了这种协议提供多流的能力。
下面让我们开始介绍 IP 堆栈的内容。
IP 堆栈
Internet 协议套件被划分成几层;每层都提供特定功能,如图 1 所示。
自下而上:
-
链路层(link layer) 提供了通信介质的物理接口(例如以太网设备)。
-
网络层(network layer) 负责管理网络中的报文移动,具体来说就是确保报文都到达自己的目标(也称为路由)。
-
传输层(transport layer) 为应用层控制了报文在两台主机之间的流动。它还代表通信的应用程序端点,称为 端口(port)。
- 最后,应用层(application layer) 对通过套接字传递数据具有深刻的意义。这些数据可能包括通过简单邮件传输协议(Simple Mail Transport Protocol,SMTP)发送的 e-mail 消息,或通过超文本传输协议(Hypertext Transport Protocol,HTTP)呈现的 Web 页面。
所有应用层协议都使用套接字层作为与传输层协议之间的接口。Sockets API 是由 UC Berkeley 在 BSD UNIX® 操作系统上开发的。
在深入钻研 SCTP 之前,让我们首先简单回顾一下传统的传输层协议。
传输层协议
两种最流行的传输层协议是传输控制协议(TCP)和用户数据报协议(UDP):
- TCP 是一种可靠的协议,它可以确保有序地发送数据,并管理网络中的拥塞问题。
- UDP 是一种面向消息的协议,它不能确保有序地发送数据,也无法管理网络拥塞的问题。
然而,UDP 是一种快速协议,可以保护自己传输的消息的边界。
本文引出了另外一个选择:SCTP。它提供了像 TCP 一样可靠、有序地发送数据的功能,但却以像 UDP 一样面向消息的方式来进行操作,这可以保护消息边界。SCTP 还提供了几个高级特性:
- 多宿主(Multi-homing)
- 多流(Multi-streaming)
- 初始化保护(Initiation protection)
- 消息分帧(Message framing)
- 可配置的无序发送(Configurable unordered delivery)
- 平滑关闭(Graceful shutdown)
SCTP 的关键特性
SCTP 相对于传统的传输层协议来说,两个重要的增强是终端主机的多宿主和多流功能。
多宿主
多宿主 为应用程序提供了比 TCP 更高的可用性。多宿主主机就是一台具有多个网络接口的主机,因此可以通过多个 IP 地址来访问这台主机。在 TCP 中,连接(connection) 是指两个端点之间的一个通道(在这种情况下,就是两台主机的网络接口之间的一个套接字)。SCTP 引入了 联合(association) 的概念,它也是存在于两台主机之间,但可以使用每台主机上的多个接口进行协作。
图 2 阐述了 TCP 连接与 SCTP 联合之间的区别。
图 2. TCP 连接与 SCTP 联合
该图的上面部分是 TCP 连接,每个主机都只包含一个网络接口;连接是在每个客户机和服务器之间的单个接口之间建立的。在建立连接时,就被绑定到了每个接口上。
在该图的下面部分中,您可以看到这样一个架构:每台主机上都包含两个网络接口。通过独立网络提供了两条路径,一条是从接口 C0 到 S0,另外一条是从接口 C1 到 S1。在 SCTP 中,这两条路径可以合并到一个联合中。
SCTP 负责使用内嵌的 heartbeat 机制来监视联合的路径;在检测到一条路径失效时,协议就会通过另外一条路径来发送通信数据。应用程序甚至都不必知道发生了故障恢复。
故障转移也可以用于维护网络应用程序的连通性。例如,让我们来考虑一台包含一个无线 802.11 接口和一个以太网接口的笔记本的例子。当笔记本放到固定的位置上时,我们倾向于使用高速的以太网接口(在 SCTP 中称为 主地址(primary address));但是在这个连接丢失时(例如离开了固定位置),连接可迁移到无线接口上。在返回固定位置时,以太网连接会被重新检测到,通信就可以在这个接口上恢复。这是一种能提供更高的可用性和可靠性的强大机制。
多流
从某种意义上来讲,SCTP 连接与 TCP 连接类似,不同之处只是 SCTP 能够在一个联合中支持多流机制。一个联合中的所有流都是独立的,但均与该联合相关(请参见图 3)。
图 3. SCTP 联合与流之间的关系
每个流都给定了一个流编号,它被编码到 SCTP 报文中,通过联合在网络上传送。多流非常重要,因为阻塞的流(例如等待重传的流会导致报文的丢失)不会影响同一联合中的其他流。这个问题统称为 head-of-line blocking(对头阻塞)。TCP 很容易出现这类阻塞问题。
多流如何在传输数据时提供更好的响应性呢?例如,HTTP 协议会在相同套接字上共享控制和数据。Web 客户机从服务器上请求一个文件,服务器通过相同的连接将这个文件发回给客户机。多流的 HTTP 服务器可以提供更好的交互能力,因为在联合中各单独的流上可以处理多个请求。这种功能可以并行化响应,尽管速度不一定会更快,但可以同时加载 HTML 和图像映像,从而表现出更好的响应性。
多流处理是 SCTP 的一个重要特性,尤其是在协议的设计中考虑一些控制和数据的问题时更是如此。在 TCP 中,控制和数据通常都是通过相同的连接进行共享的,这可能会产生问题,因为控制报文可能会在数据报之后延时。如果控制和数据被划分成单独的流,控制数据就可以以一种更及时的方式进行处理,从而可以更好地利用可用资源。
初始化保护
TCP 和 SCTP 中对新连接的初始化是通过报文握手来完成的。在 TCP 中,这种机制称为 三次握手(three-way handshake)。客户机向服务器首先发送一个 SYN
报文(Synchronize 的简写),服务器使用一个 SYN-ACK
报文进行响应(Synchronize-Acknowledge)。最后,客户机使用一个 ACK
报文确认已接收到报文(请参见图 4)。
图 4. TCP 和 STCP 握手使用的报文交换
当恶意客户机使用虚假的源地址来伪造一个 IP 报文时,TCP 就会出现问题了,这会大量 TCP SYN
报文攻击服务器。服务器在接收SYN
报文之前,要为连接分配资源,但是在大量产生 SYN
报文的情况下,最终会耗尽自己的资源,从而无法处理新的请求。这种情况就称为 服务拒绝(Denial of Service)(DoS)攻击。
SCTP 可以通过一种 4 次握手的机制并引入了 cookie 的概念来有效地防止这种攻击的产生。在 SCTP 中,客户机使用一个 INIT
报文发起一个连接。服务器使用一个 INIT-ACK
报文进行响应,其中就包括了 cookie(标识这个连接的惟一上下文)。客户机然后就使用一个 COOKIE-ECHO
报文进行响应,其中包含了服务器所发送的 cookie。现在,服务器要为这个连接分配资源,并通过向客户机发送一个 COOKIE-ACK
报文对其进行响应。
要解决使用这种 4 次握手机制解决延时数据移动的问题,SCTP 允许把数据包含到 COOKIE-ECHO
和 COOKIE-ACK
报文中。
消息分帧
使用消息分帧机制,就可以保护消息只在一个边界内通过 socket 进行通信;这意味着如果客户机向服务器先发送 100 个字节,然后又发送 50 个字节。那么服务器就会在两次读取操作中分别读取到 100 个字节和 50 个字节。UDP 也是这样进行操作,这对于面向消息的协议非常有益。
与此不同,TCP 是按照字节流的方式进行操作。如果没有分帧机制,一端接收到的数据可能比另外一端发送的数据多或少(这会将一次写操作划分成多次操作,或者将多次写操作合并到一个读操作中)。这种行为需要在 TCP 之上进行操作的面向消息的协议可以在应用层中提供数据缓冲和消息分帧机制(这可能是一项复杂的任务)。
SCTP 在数据传输中提供了消息分帧功能。当一端对一个套接字执行写操作时,可确保对等端读出的数据大小与此相同(请参见图 5)。
图 5. UDP/SCTP 中的消息分帧与面向字节流协议的比较
对于面向流的数据来说,例如音频和视频数据,可以没有分帧机制。
可配置的无序发送
SCTP 中的消息的传输十分可靠,但未必是按照想要的次序来传输的。TCP 可以确保数据是按照次序发送的(考虑到 TCP 是一种流协议,这是一件好事)。UDP 无法确保有序地发送数据。但是如果需要,您也可以在 SCTP 中配置流来接受无序的消息。
这种特性在面向消息的协议中可能非常有用,因为其中的消息都是独立的,次序并不重要。另外,您可以在一个联合中按照逐个流配置无序发送。
平滑关闭
TCP 和 SCTP 都是基于连接的协议,而 UDP 则是一种无连接的协议。TCP 和 SCTP 都需要在对等的两端建立和拆除连接。SCTP 与 TCP 中关闭连接的不同之处在于 TCP 中连接的删除是半关闭(half-close) 的。
图 6 给出了 TCP 和 SCTP 的关闭序列。
图 6. TCP 和 SCTP 的连接结束序列
在 TCP 中,一端可以关闭自己这端的 socket(这样会导致发送一个 FIN
报文),但是仍然可以继续接收数据。FIN
说明这个端点不会再发送数据,但是在这一端关闭自己这端的套接字之前,它一直可以继续传输数据。应用程序很少使用这种半关闭状态,因此 SCTP 的设计者就选择放弃这种状态,并将其替换成了一个显式的终结序列。当一端关闭自己的套接字时(导致产生一个 SHUTDOWN
原语),对等的两端全部需要关闭,将来任何一端都不允许再进行数据的移动了。
多流的展示
现在您已经了解了 SCTP 的基本特性了,接下来让我们来看一下使用 C 编程语言编写的一个样例服务器和客户机,并展示 SCTP 的多流特性。
这个例子开发了一个服务器,它实现了一种形式的日期查询协议。这个传统的服务器会在连接上来的客户机上打印当前时间,但是对于 SCTP 来说,我们会在流 0 上打印本地时间,在流 1 上打印格林威治时间(GMT)。这个例子让我们可以展示如何使用这些 API 来开发流通信。
图 7 对整个过程进行了归纳,它不但从套接字 API 的角度展示了应用程序的流程,而且还从客户机和服务器的角度介绍了它们之间的关系。
图 7. 在多流日期查询服务器和客户机中使用的套接字函数
这些应用程序是在 GNU/Linux 操作系统上开发的,其内核版本是 2.6.11,并且包含了 Linux Kernel SCTP 项目(lksctp)。其中非标准的 socket 函数是在 lksctp 工具包中提供的,这个工具包可以从 SourceForge 上获得。请参看 参考资料 中的链接。
daytime 服务器
清单 1 给出了这个多流 daytime 服务器的代码。为了可读性更好,我们在清单 1 中忽略了所有的错误检查,但是 这些展示错误检查机制的代码 与其他 SCTP 套接字扩展一样都可以通过给出的链接下载到。
清单 1. 使用多流机制为 SCTP 编写的日期查询服务器
int main()
{
int listenSock, connSock, ret;
struct sockaddr_in servaddr;
char buffer[MAX_BUFFER+1];
time_t currentTime;
/* Create SCTP TCP-Style Socket */
listenSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP );
/* Accept connections from any interface */
bzero( (void *)&servaddr, sizeof(servaddr) );
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
servaddr.sin_port = htons(MY_PORT_NUM);
/* Bind to the wildcard address (all) and MY_PORT_NUM */
ret = bind( listenSock,
(struct sockaddr *)&servaddr, sizeof(servaddr) );
/* Place the server socket into the listening state */
listen( listenSock, 5 );
/* Server loop... */
while( 1 ) {
/* Await a new client connection */
connSock = accept( listenSock,
(struct sockaddr *)NULL, (int *)NULL );
/* New client socket has connected */
/* Grab the current time */
currentTime = time(NULL);
/* Send local time on stream 0 (local time stream) */
snprintf( buffer, MAX_BUFFER, "%s\n", ctime(¤tTime) );
ret = sctp_sendmsg( connSock,
(void *)buffer, (size_t)strlen(buffer),
NULL, 0, 0, 0, LOCALTIME_STREAM, 0, 0 );
/* Send GMT on stream 1 (GMT stream) */
snprintf( buffer, MAX_BUFFER, "%s\n",
asctime( gmtime( ¤tTime ) ) );
ret = sctp_sendmsg( connSock,
(void *)buffer, (size_t)strlen(buffer),
NULL, 0, 0, 0, GMT_STREAM, 0, 0 );
/* Close the client connection */
close( connSock );
}
return 0;
}
清单 1 中的服务器首先创建服务器的套接字(使用 IPPROTO_SCTP
来创建一个 SCTP 的一对一的套接字)。然后创建一个 sockaddr
结构,指定这个连接可以从任何本地接口上创建(使用通配符地址 INADDR_ANY
)。我们使用 bind
调用将这个 sockaddr
结构绑定到 socket 上,然后将服务器套接字设置成监听状态。现在就可以接收到达的连接了。
相关推荐
### SCTP 优化网络 #### 流控制传输协议(SCTP)概述 流控制传输协议(Stream Control Transmission Protocol,简称SCTP)是一种基于互联网的传输层协议,它结合了TCP(传输控制协议)和UDP(用户数据报协议)的优点...
- 证实和避免拥塞:通过确认机制和适当的拥塞控制,SCTP优化了网络传输性能。 - 消息块绑定:SCTP允许将多个用户消息捆绑在一个SCTP数据包中,以降低传输开销。 - 分组的有效性:SCTP可以检测数据包是否在传输...
6. **分析结果**:如果包含分析结果,那么用户可以参考这些数据来评估SCTP在不同网络环境下的表现,从而优化其在网络中的使用。 总的来说,这个压缩包对那些想在NS2中模拟SCTP协议的研究者或学生来说非常有用。通过...
这对于理解网络协议设计原理、优化性能或开发基于SCTP的应用程序都至关重要。 由于SCTP在互联网中的应用逐渐增加,学习和理解其源码可以帮助开发者更好地利用这一协议,创建更高效、可靠的网络服务。无论是为了学术...
- **网络优化**:在部署新服务或升级硬件时,使用iperf3进行测试,可以确保网络配置达到预期的性能标准。 - **科研与教育**:在学术研究中,iperf3常用于实验数据收集,帮助理解网络协议的性能特性。 7. **代码...
7. **性能优化**:通过分析SCTP协议栈的实现,开发者可以优化传输效率,例如调整参数设置以适应不同的网络条件,或者改进多路径选择策略。 8. **社区与文档**:开源项目通常有活跃的开发者社区,提供技术支持和讨论...
- **优化了性能**:改进了拥塞控制算法,提高了网络效率。 - **增加了新特性**:引入了新的功能选项,扩展了协议的应用范围。 #### 七、约定与格式 SCTP定义了一系列特定的字段和参数格式,用于实现其各种功能。...
描述提到“ns2.34下sctp协议的仿真源码”,这意味着包含的源代码适用于NS-2的特定版本——2.34,该版本是一个广泛使用的网络模拟工具,用于研究和实验各种网络协议和拓扑。源代码可以用来理解和分析SCTP的工作机制,...
4. **故障恢复与重传策略**:SCTP采用基于确认的重传机制,但比TCP更复杂,它可以检测并快速恢复网络故障,如使用基于记录边界的心跳来检测丢失的分片。 5. **故障隔离**:当网络中的一个路径出现问题时,SCTP可以...
SCTP,全称Stream Control Transmission Protocol(流控制传输协议),是一种面向连接的、可靠的、基于分片的数据传输协议,广泛应用于VoIP、多媒体传输和网络协议栈中。`lksctp-tools`是一个开源的SCTP链路测试工具...
使用SCTP协议的嵌入式Linux系统在物联网、工业自动化、远程监控等领域有着广泛的应用前景,因为它能够在不可靠的网络条件下提供稳定、高效的数据传输服务。对于那些对实时性和可靠性要求较高的应用,例如语音和视频...
在SCTP协议制定以前,基于IP网络上的七号信令(SS7信令)的传输多使用UDP和TCP协议。然而,UDP作为无连接的协议,难以保证传输的可靠性,而TCP虽然能够提供可靠传输,却存在头阻塞(Head-of-Line Blocking)、实时性...
5. **消息块绑定**:SCTP支持将多个数据段封装在一个传输包中,每个数据段可以关联不同的流,这样可以优化网络资源的使用。 6. **分组的有效性**:SCTP协议检查接收到的每一个分组,确保其完整性,防止受到攻击或...
在深入理解SCTP协议的基础上,开发者可以利用这样的bit mask技术来优化网络流量的处理,比如过滤不需要的chunk,提高处理效率,或者实现特定的QoS(服务质量)策略。这可能涉及到对SCTP的多流特性、确认机制、错误...
SCTP(Stream Control Transmission Protocol)是一种面向连接的、可靠的传输协议,主要设计用于网络通信,特别是IP电话、数据传输和互联网服务提供商...对于那些想要定制或优化SCTP行为的人来说,这是一个宝贵的资源。
在“NS2 SCTP TCL wireless”描述中,“TCL”是指使用这种脚本语言来编写NS2的配置和实验脚本。TCL是一种简单易学的命令式编程语言,非常适合进行快速原型开发和实验设定。用户可以通过TCL脚本来创建复杂的网络拓扑...
NS-2是一个广泛使用的开源网络模拟工具,可以用来研究和测试各种网络协议和算法,包括SCTP。 “SCTP tcl”指的是使用TCL(Tool Command Language)脚本语言来实现或控制SCTP协议的代码。TCL是一种动态编程语言,常...
4. **单个SCTP包内捆绑多个用户消息**:优化网络带宽利用,减少网络开销。 5. **网络级容错通过两端多宿主的支持**:增强网络故障的容忍度,提升系统的稳定性和可用性。 ### SCTP的设计理念 SCTP的设计充分考虑了...