//sample SCTP server application using lksctp //alexkr.com #include #include #include #include #include #include #include #include #include #include #define RECVBUFSIZE 4096 #define PPID 1234 int main(int argc, char *argv[]) { int SctpScocket, n, flags; socklen_t from_len; //forget about memset(,0,) struct sockaddr_in addr = {0}; struct sctp_sndrcvinfo sinfo = {0}; struct sctp_event_subscribe event = {0}; char pRecvBuffer[RECVBUFSIZE + 1] = {0}; char * szAddress; int iPort; char * szMsg; int iMsgSize; if (argc < 3) { printf("Use parameters: bind_to_address port response\n"); return 0; } //get the arguments szAddress = argv[1]; iPort = atoi(argv[2]); szMsg = argv[3]; iMsgSize = strlen(szMsg); if (iMsgSize > 1024) { printf("Message is too big for this test\n"); return 0; } //here we may fail if sctp is not supported if ((SctpScocket = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0) { printf("After socket errno: %d\n", errno); perror("Description: "); return 0; } printf("socket created...\n"); //make sure we receive MSG_NOTIFICATION if (setsockopt(SctpScocket, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)) < 0) { printf("After setsockopt errno: %d\n", errno); perror("Description: "); return 0; } printf("setsockopt succeeded...\n"); addr.sin_family = AF_INET; addr.sin_port = htons(iPort); addr.sin_addr.s_addr = inet_addr(szAddress); //bind to specific server address and port if (bind(SctpScocket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { printf("After bind errno: %d\n", errno); perror("Description: "); return 0; } printf("bind succeeded...\n"); //wait for connections if (listen(SctpScocket, 1) < 0) { printf("After listen errno: %d\n", errno); perror("Description: "); return 0; } printf("listen succeeded...\n"); while(true) { //each time erase the stuff flags = 0; memset((void *)&addr, 0, sizeof(struct sockaddr_in)); from_len = (socklen_t)sizeof(struct sockaddr_in); memset((void *)&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); n = sctp_recvmsg(SctpScocket, (void*)pRecvBuffer, RECVBUFSIZE, (struct sockaddr *)&addr, &from_len, &sinfo, &flags); if (-1 == n) { printf("Error with sctp_recvmsg: -1... waiting\n"); printf("errno: %d\n", errno); perror("Description: "); sleep(1); continue; } if (flags & MSG_NOTIFICATION) { printf("Notification received!\n"); printf("From %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); } else { printf("Received from %s:%u on stream %d, PPID %d.: %s\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), sinfo.sinfo_stream, ntohl(sinfo.sinfo_ppid), pRecvBuffer ); } //send message to client printf("Sending to client: %s\n", szMsg); if (sctp_sendmsg(SctpScocket, (const void *)szMsg, iMsgSize, (struct sockaddr *)&addr, from_len, htonl(PPID), 0, 0 /*stream 0*/, 0, 0) < 0) { printf("After sctp_sendmsg errno: %d\n", errno); perror("Description: "); return 0; } //close server when exit is received if (0 == strcmp(pRecvBuffer, "exit")) { break; } }//while printf("exiting...\n"); if (close(SctpScocket) < 0) { perror("close"); } return (0); }