流控制传输协议(Stream Control Transmission Protocol,SCTP)是一种可靠的传输协议,它在两个端点之间提供稳定、有序的数据传递服务(非常类似于 TCP),并且可以保护数据消息边界(例如 UDP)。然而,与 TCP 和 UDP 不同,SCTP 是通过多宿主(Multi-homing)和多流(Multi-streaming)功能提供这些收益的,这两种功能均可提高可用性。在本文中,我们将学习 Linux® 2.6 内核中 SCTP 的关键特性,并通过服务器和客户机的源代码了解该协议提供多流的能力。//INIT sctp协议 IETFSCTP 是在 IP 网络上使用的一种可靠的通用传输层协议。尽管 SCTP 协议最初是为发送电话信号而设计的(RFC 2960),但带来了一个意外的收获:它通过借鉴 UDP 的优点解决了 TCP 的某些局限。SCTP 提供的特性使套接字初始化的可用性、可靠性和安全性都得以提高。(图 1 给出了 IP 堆栈的层次化架构。)
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;} |
int main(){ int connSock, in, i, flags; struct sockaddr_in servaddr; struct sctp_sndrcvinfo sndrcvinfo; struct sctp_event_subscribe events; char buffer[MAX_BUFFER+1]; /* Create an SCTP TCP-Style. Socket */ connSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP ); /* Specify the peer endpoint to which we'll connect */ bzero( (void *)&servaddr, sizeof(servaddr) ); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(MY_PORT_NUM); servaddr.sin_addr.s_addr = inet_addr( "127.0.0.1" ); /* Connect to the server */ connect( connSock, (struct sockaddr *)&servaddr, sizeof(servaddr) ); /* Enable receipt of SCTP Snd/Rcv Data via sctp_recvmsg */ memset( (void *)&events, 0, sizeof(events) ); events.sctp_data_io_event = 1; setsockopt( connSock, SOL_SCTP, SCTP_EVENTS, (const void *)&events, sizeof(events) ); /* Expect two messages from the peer */ for (i = 0 ; i < 2 ; i++) { in = sctp_recvmsg( connSock, (void *)buffer, sizeof(buffer), (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags ); /* Null terminate the incoming string */ buffer[in] = 0; if (sndrcvinfo.sinfo_stream == LOCALTIME_STREAM) { printf("(Local) %s\n", buffer); } else if (sndrcvinfo.sinfo_stream == GMT_STREAM) { printf("(GMT ) %s\n", buffer); } } /* Close our socket and exit */ close(connSock); return 0;} |
通信人家园 (https://www.txrjy.com/) | Powered by C114 |