Design, implementation and evaluation issues of local area network devices 期末 DEMO Elementary SCTP Socket Functions & Client/Server Example 陳旻槿
SCTP Socket Types Maintain consistency with the existing sockets APIs –The SCTP sockets API extension must stay consistency with the existing UDP,TCP,IPv4,and IPv6 sockets API. SCTP socket API comes in two forms: one-to- one and one-to-many. –The one-to-one used to be called the a “TCP style” socket. –The one-to-many at one time was known by the “UDP style” socket.
Functions Discussion socket() Applications calls socket() to create a socket descriptor to represent an SCTP endpoint. bind() Applications use bind() to pass an address to be associated with an SCTP endpoint to the system. listen() Applications use listen() to ready the SCTP endpoint for accepting inbound associations. accept() Applications use accept() call to remove an established SCTP association from the accept queue of the endpoint.
Functions Discussion connect() Applications use connect() to initiate an association to a peer. sendmsg() and recvmsg() An application uses sendmsg() and recvmsg() call to transmit data to and receive data from its peer. close() Applications use close() to gracefully close down an association. sctp_bindx() Allows an application to bind a set of addresses instead of one or all addresses.
sctp_initmsg() SCTP_INITMSG – Can be used to get or set the default INIT/INIT-ACK settings such as number of streams allowed in or requested out. sctp_sendmsg() This call will allow the caller to specify on the command line things like the stream number and other SCTPish information to be sent with a message. sctp_recvmsg() This call is used to receive a message but also a sctp_sndrcvinfo structure with details on the message (e.g. The stream number and stream sequence number).
SCTP one-to-one style socket A typical server in one-to-one style uses the following system call sequence to prepare an SCTP endpoint for servicing requests: 1. socket() 2. bind() 3. listen() 4. accept() 5. close()
A typical client uses the following system call sequence to setup an association with a server to request services: 1. socket() 2. connect() 3. close() After returning from connect(), the client uses send and recv calls to send out requests and receive responses from the server.
Server (connection-oriented protocol) socket() accept() send() or sendmsg() socket() connect() recv() or recvmsg() bind() send() or sendmsg() recv() or recvmsg() blocks until connection from client data (request) data (reply) Client (connection-oriented protocol) process request sctp_bindx() multiple addressessingle addresses listen() close() SCTP_INITMSG
one-to-many style socket A typical server using a one-to-many style socket will do a socket() call, followed by a listen() and sendmsg() / recvmsg(). Note that the connect() and accept() call are not needed. A typical server in this style uses the following socket calls in sequence to prepare an endpoint for servicing requests: 1. socket() 2. bind() 3. listen() 4. recvmsg() and sendmsg() 5. close()
A typical client uses the following calls in sequence to setup an association with a server to request services: 1. socket() 2. sendmsg() 3. recvmsg() 4. close()
Server socket() sendto( )/ sendmsg() socket() recvfrom() / recvmsg() bind() sendto( )/ sendmsg() recvfrom() / recvmsg() data (request) data (reply) Client process request listen() close()
Multi-streaming demo 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.
socket() accept() sctp_ sendmsg() socket() connect() sctp_ sendmsg() bind() Sctp_recvmsg listen() close() Sctp_recvmsg Connection establishment Stream 0 Stream 1 Connection termination Client Server Sockets functions used in the multi-streaming daytime server and client
Server code (1/2) 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 code (2/2) /* 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;}
Client code (1/2) 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( " " ); /* 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) );
Client code (1/2) /* 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; }