- Get link
- X
- Other Apps
Featured Post
Posted by
Unknown
on
- Get link
- X
- Other Apps
Here's a simple implementation of SCTP server and client in C
This is how the connection is established :
The Client initiates the connection with an INIT packet . Server replies back by sending the INIT-ACK.
This packet also contains a unique context which identifies this connection. This context is called as COOKIE. The client then responds with a COOKIE-ECHO with the cookie sent by the server.
Now the server allocates the necessary resources required by the connection and replies back to the client with COOKIE-ACK.
And this is how the connection is terminated.
This is a detailed connection diagram for this program is as follows
Note: To compile this code, sctp dev libraries are needed .
For ubuntu : sudo apt-get install libsctp-dev
This is how the connection is established :
This packet also contains a unique context which identifies this connection. This context is called as COOKIE. The client then responds with a COOKIE-ECHO with the cookie sent by the server.
Now the server allocates the necessary resources required by the connection and replies back to the client with COOKIE-ACK.
And this is how the connection is terminated.
This is a detailed connection diagram for this program is as follows
//SCTPServer.C To compile - gcc sctpserver.c - o server - lsctp #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <time.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <netinet/sctp.h> #define MAX_BUFFER 1024 #define MY_PORT_NUM 62324 /* This can be changed to suit the need and should be same in server and client */ int main () { int listenSock, connSock, ret, in, flags, i; struct sockaddr_in servaddr; struct sctp_initmsg initmsg; struct sctp_event_subscribe events; struct sctp_sndrcvinfo sndrcvinfo; char buffer[MAX_BUFFER + 1]; listenSock = socket (AF_INET, SOCK_STREAM, IPPROTO_SCTP); if(listenSock == -1) { printf("Failed to create socket\n"); perror("socket()"); exit(1); } 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); ret = bind (listenSock, (struct sockaddr *) &servaddr, sizeof (servaddr)); if(ret == -1 ) { printf("Bind failed \n"); perror("bind()"); close(listenSock); exit(1); } /* Specify that a maximum of 5 streams will be available per socket */ memset (&initmsg, 0, sizeof (initmsg)); initmsg.sinit_num_ostreams = 5; initmsg.sinit_max_instreams = 5; initmsg.sinit_max_attempts = 4; ret = setsockopt (listenSock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof (initmsg)); if(ret == -1 ) { printf("setsockopt() failed \n"); perror("setsockopt()"); close(listenSock); exit(1); } ret = listen (listenSock, 5); if(ret == -1 ) { printf("listen() failed \n"); perror("listen()"); close(listenSock); exit(1); } while (1) { char buffer[MAX_BUFFER + 1]; int len; //Clear the buffer bzero (buffer, MAX_BUFFER + 1); printf ("Awaiting a new connection\n"); connSock = accept (listenSock, (struct sockaddr *) NULL, (int *) NULL); if (connSock == -1) { printf("accept() failed\n"); perror("accept()"); close(connSock); continue; } else printf ("New client connected....\n"); in = sctp_recvmsg (connSock, buffer, sizeof (buffer), (struct sockaddr *) NULL, 0, &sndrcvinfo, &flags); if( in == -1) { printf("Error in sctp_recvmsg\n"); perror("sctp_recvmsg()"); close(connSock); continue; } else { //Add '\0' in case of text data buffer[in] = '\0'; printf (" Length of Data received: %d\n", in); printf (" Data : %s\n", (char *) buffer); } close (connSock); } return 0; }
//SCTPClient.C // To compile - gcc sctpclt.c -o client -lsctp #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <netinet/sctp.h> #include <arpa/inet.h> #define MAX_BUFFER 1024 #define MY_PORT_NUM 62324 /* This can be changed to suit the need and should be same in server and client */ int main (int argc, char* argv[]) { int connSock, in, i, ret, flags; struct sockaddr_in servaddr; struct sctp_status status; char buffer[MAX_BUFFER + 1]; int datalen = 0; /*Get the input from user*/ printf("Enter data to send: "); fgets(buffer, MAX_BUFFER, stdin); /* Clear the newline or carriage return from the end*/ buffer[strcspn(buffer, "\r\n")] = 0; /* Sample input */ //strncpy (buffer, "Hello Server", 12); //buffer[12] = '\0'; datalen = strlen(buffer); connSock = socket (AF_INET, SOCK_STREAM, IPPROTO_SCTP); if (connSock == -1) { printf("Socket creation failed\n"); perror("socket()"); exit(1); } 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"); ret = connect (connSock, (struct sockaddr *) &servaddr, sizeof (servaddr)); if (ret == -1) { printf("Connection failed\n"); perror("connect()"); close(connSock); exit(1); } ret = sctp_sendmsg (connSock, (void *) buffer, (size_t) datalen, NULL, 0, 0, 0, 0, 0, 0); if(ret == -1 ) { printf("Error in sctp_sendmsg\n"); perror("sctp_sendmsg()"); } else printf("Successfully sent %d bytes data to server\n", ret); close (connSock); return 0; }
Note: To compile this code, sctp dev libraries are needed .
For ubuntu : sudo apt-get install libsctp-dev
Comments
undefined reference to `sctp_recvmsg'
ReplyDeletei got this error it is not working
will please solve this problem
undefined reference to `sctp_recvmsg'|
ReplyDeletesolve this error
It seems that sctp header file is not included properly. Check if it is present in the standard location of gcc.
ReplyDeleteThank you for writing this article, I have used it as a reference in my article: SCTP multi-homing with dynamic address reconfiguration http://rainbowtux.blogspot.be/2012/10/sctp-multi-homing-with-dynamic-address.html#.UIvlHtE7jTk
ReplyDeleteKind regards,
It is no multi-homing. It is example of multi streams. It's different concepts.
DeleteIn order to resolve the missing sctp.h file issue, you have to load the libsctp-dev. Use sudo apt-get install libsctp-dev on debian or Ubuntu and sudo yum install libsctp-dev on Fedora and Centos.
ReplyDeleteTo resolve the undefined reference to sctp_recvmsg, you have to link with libsctp. To do that, use the -l sctp switch to the compiler, e.g.
gcc SCTP_server.c -l sctp -o SCTP_server
To clear the buffer,add code
ReplyDeletememset(buffer, 0, MAX_BUFFER + 1);
between the "New client connected...." printf and the sctp_recvmsg.
When the messages are text, the memset is OK, but not the quickest way. In general, use the message length as returned by sctp_recvmsg.
DeleteIn this case,
in = sctp_recvmsg ....
buffer[in] = (char) NULL;
printf .....
More robust code would deal with the fact that "The sctp_recvmsg() function returns -1 when an error occurs." (source: http://docs.oracle.com/cd/E19963-01/html/821-1602/sockets-17.html )
hi i tried to execute this but it is showing the following error on the client side
ReplyDeleteconnect : connection denied
please resolve this problem
Did you run the program as root ? what kind of platform are you using ?
DeleteAlso try debugging the code with gdb , it will tell you the exact error code.
hi, even i am facing the same problem. it says connection refused.i ran the program both on root as well as on the normal user mode. i even tried debugging the code,but it dint really work. Kindly help.
DeleteHello folks, in my case the code runs perfectly but the output way different than expected.
ReplyDeletethe server seems not to wait for the client to send data to it.. it comes blank and then on the client side i'm asked to enter data..
For the server side -->
$ ./bin/sctp_server
Awaiting a new connection
New client connected....
Data :
Awaiting a new connection
For the Client side -->
$ ./bin/sctp_client
Data sent by Client : qwer
Some more Issues ::
ReplyDeleteServer
$ ./bin/sctp_server
Awaiting a new connection
New client connected...
Data :
Awaiting a new connection
Client
$./bin/sctp_client
There is no point entering data when the client asks, the server always displays data as blank.
Can you try the new code ?
Deletecan you please guide on how to run this code?
ReplyDeleteis there any order that has to be followed?
Please follow the instructions in the comments at the top of each file.
ReplyDeleteTo run server: ./server
To run client: ./client
the server seems not to wait for the client to send data to it.. it comes blank and then on the client side i'm asked to enter data..
ReplyDeleteFor the server side -->
$ ./bin/sctp_server
Awaiting a new connection
New client connected....
Data :
Awaiting a new connection
please help!!!
Hi,
DeleteI have modified the code to handle text data. Please try the new one.
Although, I was able to run the existing one perfectly fine.
Also please post if you have made any modifications
Simple and Impressive.. worked just like that !!!
ReplyDeleteHey, I am running the server code on a different machine and the client on my local machine. Both are in the same network. They are not able to connect. However, I can connect if use udp client-server sockets. Any help?
ReplyDeleteNote, make sure to set flags to 0 (`int flags = 0`), because otherwise the pointer might point to an address which is non-0 and it would set flags that you don't want to set:
ReplyDelete```
(...)
man sctp_recvmsg
(...)
The value of msg_flags pointer should be initialized to 0 to avoid unexpected behavior
```