//sample SCTP client 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, in, flags; socklen_t opt_len; char * szAddress; int iPort; char * szMsg; int iMsgSize; //forget about memset(,0,); struct sockaddr_in servaddr = {0}; struct sctp_status status = {0}; struct sctp_sndrcvinfo sndrcvinfo = {0}; struct sctp_event_subscribe events = {0}; struct sctp_initmsg initmsg = {0}; char * szRecvBuffer[RECVBUFSIZE + 1] = {0}; socklen_t from_len = (socklen_t) sizeof(struct sockaddr_in); if (argc < 3) { printf("Use parameters: send_to_address port message\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; } printf("Starting SCTP client connection to %s:%u\n", szAddress, iPort); //here we fail when Linux does not support SCTP if ((SctpScocket = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0) { printf("After socket errno: %d\n", errno); perror("Description: "); return 0; } printf("socket created...\n"); //set the association options initmsg.sinit_num_ostreams = 1; //number of output streams can be greater if (setsockopt( SctpScocket, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg))<0 ) { printf("After setsockopt errno: %d\n", errno); perror("Description: "); return 0; } printf("setsockopt succeeded...\n"); //other endpoint to make association with bzero( (void *)&servaddr, sizeof(servaddr) ); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(iPort); servaddr.sin_addr.s_addr = inet_addr( szAddress ); //establish SCTP association if (connect( SctpScocket, (struct sockaddr *)&servaddr, sizeof(servaddr) ) < 0) { printf("After connect errno: %d\n", errno); perror("Description: "); return 0; } printf("connect succeeded...\n"); //check status opt_len = (socklen_t) sizeof(struct sctp_status); if (getsockopt(SctpScocket, IPPROTO_SCTP, SCTP_STATUS, &status, &opt_len) < 0) { printf("After getsockopt errno: %d\n", errno); perror("Description: "); return 0; }else { printf("Association ID\t\t= %d\n", status.sstat_assoc_id ); printf("Receiver window size\t= %d\n", status.sstat_rwnd ); } //send message to server printf("Sending to server: %s\n", szMsg); if (sctp_sendmsg(SctpScocket, (const void *)szMsg, iMsgSize, NULL, 0, htonl(PPID), 0, 0 /*stream 0*/, 0, 0) < 0) { printf("After sctp_sendmsg errno: %d\n", errno); perror("Description: "); return 0; } //read response from test server in = sctp_recvmsg(SctpScocket, (void*)szRecvBuffer, RECVBUFSIZE, (struct sockaddr *)&servaddr, &from_len, &sndrcvinfo, &flags); if (in > 0 && in < RECVBUFSIZE - 1) { szRecvBuffer[in] = 0; printf("Received from server: %s\n", szRecvBuffer); return 0; } else { printf("After sctp_recvmsg errno: %d\n", errno); perror("Description: "); printf("Return: %d\n", in); } if (close(SctpScocket) < 0) { printf("After close errno: %d\n", errno); perror("Description: "); } printf("exiting...\n"); //cleanup close(SctpScocket); return 0; }