Multiple Associations with Stream Control Transmission Protocol

The elegant way SCTP handles multiple streams makes it ideal for things like chat clients.
Getting the Association ID

Many of the calls that deal with associations take an association ID as a parameter. Whereas in TCP, a connection effectively is represented by the pair of source and destination endpoint IP addresses, in SCTP, the source and destination can both be multihomed, so they will be represented by the set of source and the set of destination addresses. For one-to-many sockets, the source addresses may be shared by many associations, so I need the destination addresses to identify an association properly. For a single association, these destination addresses all belong to a single endpoint computer. The SCTP variation on getsockopt()—that is, sctp_opt_info()—is used to find an association from an address. The reason I cannot simply use getsockopt() is that I need to pass in a socket address, and the return value includes the association value. This in/out semantics is not supported by all implementations of getsockopt(). The code is:

sctp_assoc_t get_associd(int sockfd, struct sockaddr *sa, socklen_t salen) { 
    struct sctp_paddrinfo sp; 
    int sz; 
    sz = sizeof(struct sctp_paddrinfo); 
    bzero(&sp, sz); 
    memcpy(&sp.spinfo_address, sa, salen); 
    if (sctp_opt_info(sockfd, 0, SCTP_GET_PEER_ADDR_INFO, &sp, &sz) == -1) 
        perror("get assoc"); 
    return (sp.spinfo_assoc_id); 

Note that Unix Network Programming (volume 1, 3rd ed.) by W. Richard Stevens, et al., gives different code: the specification has changed since that book was written, and the above is now the preferred way (and Stevens' code doesn't work under Linux anyway).

Multiple Associations

A server can handle multiple clients in a number of ways: a TCP server can use a single server socket that listens for clients and deals with them sequentially, or it could fork off each new client connection as a separate process or thread, or it could have many sockets and poll or select between them. A UDP server typically will keep no client state and will treat each message in its entirety as a separate entity. SCTP offers another variation, roughly halfway between TCP and UDP.

An SCTP socket can handle multiple long-lived associations to many endpoints simultaneously. It supports the “connection-oriented” semantics of TCP by maintaining an association ID for each association. On the other hand, it is like UDP in that each read usually returns a complete message from a client. SCTP applications use the TCP model by using the one-to-one sockets that I have discussed in the previous two articles. And, it uses a one-to-many model, which is more like UDP by using a one-to-many socket. When you create a socket, you specify whether it is one-to-one or one-to-many. In the first article in this series, I created a one-to-one socket by the call:


To create a one-to-many socket, I simply change the second parameter:


A TCP server handles multiple connections simultaneously by essentially using concurrent reads. This is done by using multiple processes, threads, or by poll/select among many sockets. A UDP server typically uses a single read loop, handling each message as it arrives. An SCTP one-to-many server looks like a UDP server: it will bind a socket and listen. Then, instead of blocking on accept(), which would return a new one-to-one socket, it blocks on sctp_rcvmsg(), which returns a message from either a new or existing association. Pseudo-code for such a server is:

sockfd = socket(...); 
bind(sockfd, ...); 
listen(sockfd, ...); 
while (true) { 
    nread = sctp_rcvmsg(sockfd, ..., buf, ..., &info); 
    assoc_id = sinfo.sinfo_assoc_id; 
    stream = sinfo.sinfo_stream; 
    handle_message(assoc_id, stream, buf, nread); 

A client also can use the one-to-many socket model. After binding to a port (probably an ephemeral one), it can use the single socket to connect to many other endpoints and use this single socket to send messages to any of them. It even can do away with an explicit connect operation and just start sending to new endpoints (an implicit connection is done if no existing association exists).

Peeled-Off Sockets

One-to-one sockets follow the TCP model; one-to-many sockets follow the UDP model. Is it possible to have both at once? Yes, it is, to some extent. For example, you may have a server that you can talk to in two modes: ordinary user and superuser. Messages from ordinary users may be handled in UDP style, reading and just responding, while superuser connections may need to be treated differently. SCTP allows a connection on a one-to-many socket to be “peeled off” and become a one-to-one socket. This one-to-one socket may then be treated in TCP-style, while all other associations remain on the one-to-many socket.


Jan Newmarch has written many books and papers about software engineering, network programming, user interfaces and artificial intelligence, and he is currently digging into the IoT.


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

help to compile n run

rams's picture

i m currently working in redhat version 5. I read ur article n want to run the program u have provided in SCTP. During run time what r the additional parameter required except ./chat_server.c. Should i reserve the port. Please reply me.

error :: SCTP_SENDALL;

kkk's picture

i am using linux kernel 2.6.25 and as mentation in linux journal that SCTP_SENDALL is not suported by 2.6.21 but still i am getting an error in line

"sinfo.sinfo_flags |= SCTP_SENDALL;"



kaushal's picture

Dear Sir,

I have installed latest 2.6.22 kernels. of sctp but stiil my code is giving error (see below). please help me out

# cc chat_server.c -o chat_server -L /usr/lib -lsctp
chat_server.c: In function ‘main’:
chat_server.c:60: error: ‘SCTP_SENDALL’ undeclared (first use in this function)
chat_server.c:60: error: (Each undeclared identifier is reported only once
chat_server.c:60: error: for each function it appears in.)