📄 sctp-v1b.xml
字号:
<p>Now that you have some idea of the basic features of SCTP, let's look at a sample server and client written
in the C programming language that demonstrate SCTP's multi-streaming feature.</p>
<p>This example presents a server that implements a form of the daytime protocol. This traditional server emits
the current time to a connected client, but for SCTP, I emit the local time on stream 0 and Greenwich Mean Time
(GMT) on stream 1. This simple example allows me to demonstrate the APIs for stream communication. Figure 7
outlines the entire process and shows not only the flow of the application from a sockets API perspective but
also the relationships from a client and server perspective.</p>
<figure><heading refname="" type="figure" toc="no" name="" alttoc="">Figure 7. Sockets functions used in the multi-streaming daytime server and client</heading>
<img src="images\figure7.gif" width="422" height="533" alt="Sockets functions used in the multi-streaming daytime server and client"/>
</figure>
<sidebar>I've developed these applications on the GNU/Linux operating system with a 2.6.11 kernel and the Linux
Kernel SCTP project (lksctp). The nonstandard sockets functions are provided in the lksctp tools package, which
is available from sourceforge. See <a href= "#resources">Resources</a> for links.
</sidebar>
<heading toc="no" refname="" type="minor">The daytime server</heading>
<p>The multi-stream daytime server is shown in Listing 1. I've omitted all error checking from this example just to
make it a bit more readable, but the code in the downloadable .zipfile demonstrates error checking as well as
other SCTP socket extensions.</p>
<p>The server begins in Listing 1 with the creation of the server socket (using <code type="inline">IPPROTO_SCTP</code>
to create an SCTP one-to-one socket). I then create a <code type="inline">sockaddr</code> structure,
specifying that connections are permitted from any local interface (using the wildcard address,
<code type="inline">INADDR_ANY</code>). I bind this <code type="inline">sockaddr</code> structure
to the socket using the <code type="inline">bind</code> call, then place the server socket into the listening
state. At this point, incoming connections are possible.</p>
<p><b>Listing 1. Daytime server written for SCTP using multiple streams</b></p>
<code type="section">
int main()
{
int listenSock, connSock, ret;
struct sockaddr_in servaddr;
char buffer[MAX_BUFFER+1];
time_t currentTime;
/* Create SCTP TCP-Style Socket */
listenSock = <b>socket</b>( 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 = <b>htonl</b>( INADDR_ANY );
servaddr.sin_port = <b>htons</b>(MY_PORT_NUM);
/* Bind to the wildcard address (all) and MY_PORT_NUM */
ret = <b>bind</b>( listenSock,
(struct sockaddr *)&servaddr, sizeof(servaddr) );
/* Place the server socket into the listening state */
<b>listen</b>( listenSock, 5 );
/* Server loop... */
while( 1 ) {
/* Await a new client connection */
connSock = <b>accept</b>( 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(&currentTime) );
ret = <b>sctp_sendmsg</b>( 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( &currentTime ) ) );
ret = <b>sctp_sendmsg</b>( connSock,
(void *)buffer, (size_t)strlen(buffer),
NULL, 0, 0, 0, GMT_STREAM, 0, 0 );
/* Close the client connection */
<b>close</b>( connSock );
}
return 0;
}
</code>
<sidebar>Notice that SCTP uses many of the same sockets API as TCP and UDP do. Some additional API functions
are provided in the lksctp development tools (see <a href="#resources">Resources</a>).
</sidebar>
<p>In the server loop, new client connections are awaited. Upon return from the <code type="inline">accept</code>
function, a new client connection is identified by the <code type="inline">connSock</code> socket. I grab
the current time using the <code type="inline">time</code> function, then convert it to a string with
<code type="inline">snprintf</code>. With the <code type="inline">sctp_sendmsg</code> function (a
nonstandard sockets call), I can send the string to the client, specifying the particular stream
(<code type="inline">LOCALTIME_STREAM</code>). When the localtime string has been sent,
I package the current time in GMT as a string, then send this on stream <code type="inline">GMT_STREAM</code>.</p>
<p>At this point, the daytime server has fulfilled its duty, so I close the socket and await a new client connection.
That was simple; now, let's see what the daytime client must do to handle multi-streaming.</p>
<heading toc="no" refname="" type="minor">The daytime client</heading>
<p>The multi-streaming client is shown in Listing 2. In the client, I create an SCTP socket, then create a
<code type="inline">sockaddr</code> structure containing the endpoint to which it will connect. The
<code type="inline">connect</code> function then establishes a connection to the server. To retrieve the
stream number of a message, SCTP requires enabling the socket option <code type="inline">sctp_data_io_event</code>).
With this enabled, when I receive a message through the <code type="inline">sctp_recvmsg</code> API
function, I also receive a <code type="inline">sctp_sndrcvinfo</code> structure that contains the stream
number. This number allows me to discriminate between messages from stream 0 (localtime) and stream
1 (GMT).</p>
<p><b>Listing 2. Daytime client written for SCTP using multiple streams</b></p>
<code type="section">
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 = <b>socket</b>( 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 = <b>htons</b>(MY_PORT_NUM);
servaddr.sin_addr.s_addr = <b>inet_addr</b>( "127.0.0.1" );
/* Connect to the server */
<b>connect</b>( 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;
<b>setsockopt</b>( connSock, SOL_SCTP, SCTP_EVENTS,
(const void *)&events, sizeof(events) );
/* Expect two messages from the peer */
for (i = 0 ; i < 2 ; i++) {
in = <b>sctp_recvmsg</b>( 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 */
<b>close</b>(connSock);
return 0;
}
</code>
<heading refname="" type="major" toc="yes" alttoc="">The future of SCTP</heading>
<p>SCTP is a relatively new protocol, considering that it became an RFC in October 2000. Since then, it
has found its way into all major operating systems, including GNU/Linux, BSD, and Solaris. It's also
available for the Microsoft<reg>庐</reg> Windows<reg>庐</reg> operating systems as a third-party
commercial package.</p>
<p>With its availability, applications will begin to utilize SCTP as their primary transport. Traditional
applications such as FTP and HTTP have been built on the features of SCTP. Other protocols are
using SCTP, such as the Session Initiation Protocol (SIP) and the Common Channel Signaling System No.
7 (SS7). Commercially, you can find SCTP in Cisco's IOS.</p>
<p>With the inclusion of SCTP into the 2.6 Linux kernel, it's now possible to build and deploy highly available
and reliable networked applications. As an IP-based protocol, SCTP is a seamless replacement for TCP
and UDP but also extends new services, such as multi-homing, multi-streaming, and increased security.</p>
<p>This article presented a look at some of the high-level features of SCTP, and I encourage you to explore the
other capabilities that it provides. The Linux Kernel SCTP project (lksctp) provides API extensions and
documentation that will help you on your way.</p>
</docbody>
<resource-list>
<ul>
<li>Learn about other networking improvements of the <a href="http://www-128.ibm.com/developerworks/linux/library/l-net26.html">Linux 2.6 kernel</a>.</li>
<li>Find the latest Linux kernel at <a href="http://www.kernel.org">kernel.org</a>.</li>
<li>Read the Request for Comments Introduction to <a href="http://www.faqs.org/rfcs/rfc3286.html">SCTP</a>.</li>
<li>See the latest status of the <a href="http://lksctp.sourceforge.net/">Linux Kernel SCTP Project</a> at SourceForge.</li>
<li>Read the <a href="http://devworks.krcinfo.com/WebForms/ProductDetails.aspx?ProductID=0201721864"><i>SCTP Reference Guide</i></a>, written by its creators Randall Stewart and Qiaobing Xie.</li>
<li>Discover research at the University of Delaware investigating <a href="http://pel.cis.udel.edu/">alternative transport layer protocols</a>, such as SCTP.</li>
<li>Read the Internet Standard for SCTP, <a href="http://www.faqs.org/rfcs/rfc2960.html">RFC2960</a>.</li>
<li>Explore the implementation issues in the <a href="http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-sctpimpguide-13.txt"><i>SCTP Implementer's Guide Internet-Draft</i></a>.</li>
<li>Inviestigate the SCTP Sockets API Extensions in the latest <a href="http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-sctpsocket-10.txt">Internet-Draft</a>.</li>
<li>Visit the <a href="http://www.sctp.de">sctp.de</a> page for information about SCTP implementations, RFCs, and tutorials.</li>
<li>Get involved in the Signaling Transport (sigtran) <a href="http://www.ietf.org/html.charters/sigtran-charter.html">working group</a>.</li>
<li>Find more resources for Linux developers in the <a href="http://www.ibm.com/developerworks/linux/">developerWorks Linux zone</a>.</li>
<li>Visit the <a href="http://www.ibm.com/developerworks/offers/linux-speed-start/">Speed-start your Linux app</a> site for the latest no-charge trial downloads for Linux (WebSphere Studio Application Developer, WebSphere Application Server, DB2 Universal Database, Tivoli Access Manager, and Tivoli Directory Server), as well as how-to articles and tech support.</li>
<li>Get involved in the developerWorks community by participating in <a href="http://www.ibm.com/developerworks/blogs/">developerWorks blogs</a>.</li>
<li>Purchase <a href="http://devworks.krcinfo.com/WebForms/ProductList.aspx?Search=Category&id=300&parent=Linux" target="new">Linux books at discounted prices</a> in the Linux section of the Developer Bookstore.</li>
</ul>
</resource-list>
</dw-article>
</dw-document>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -