一、服务器程序
#include <stdlib.h> #include <string.h> #include <strings.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/sctp.h> #define LISTENQ 1024 #define BUFFSIZE 4096 #define SERV_PORT 9877 #define SA struct sockaddr int sctp_get_no_strms(int, struct sockaddr *, socklen_t); sctp_assoc_t sctp_address_to_associd(int, struct sockaddr *, socklen_t); int main(int argc, char **argv) { int sock_fd,msg_flags; char readbuf[BUFFSIZE]; struct sockaddr_in servaddr, cliaddr; struct sctp_sndrcvinfo sri; struct sctp_event_subscribe evnts; int stream_increment=1; socklen_t len; size_t rd_sz; if (argc == 2) { stream_increment = atoi(argv[1]); } sock_fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); bind(sock_fd, (SA *) &servaddr, sizeof(servaddr)); bzero(&evnts, sizeof(evnts)); evnts.sctp_data_io_event = 1; setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)); listen(sock_fd, LISTENQ); for ( ; ; ) { len = sizeof(struct sockaddr_in); rd_sz = sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf), (SA *)&cliaddr, &len, &sri,&msg_flags); if(stream_increment) { sri.sinfo_stream++; if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) { sri.sinfo_stream = 0; } } sctp_sendmsg(sock_fd, readbuf, rd_sz, (SA *)&cliaddr, len, sri.sinfo_ppid, sri.sinfo_flags, sri.sinfo_stream, 0, 0 ); } } int sctp_get_no_strms(int sock_fd,struct sockaddr *to, socklen_t tolen) { int retsz; struct sctp_status status; retsz = sizeof(status); bzero(&status,sizeof(status)); status.sstat_assoc_id = sctp_address_to_associd(sock_fd,to,tolen); getsockopt(sock_fd,IPPROTO_SCTP, SCTP_STATUS, &status, &retsz); return (status.sstat_outstrms); } sctp_assoc_t sctp_address_to_associd(int sock_fd, struct sockaddr *sa, socklen_t salen) { struct sctp_paddrparams sp; int siz; siz = sizeof(struct sctp_paddrparams); bzero(&sp,siz); memcpy(&sp.spp_address,sa,salen); sctp_opt_info(sock_fd,0, SCTP_PEER_ADDR_PARAMS, &sp, &siz); return (sp.spp_assoc_id); }
二、客户端程序
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <strings.h> #include <arpa/inet.h> #include <sys/socket.h> #include <netinet/sctp.h> #define MAXLINE 4096 #define SERV_PORT 9877 #define SCTP_MAXLINE 800 #define SERV_MAX_SCTP_STRM 10 #define SA struct sockaddr void err_quit(const char *, ...); void sctpstr_cli(FILE *, int, struct sockaddr *, socklen_t); void sctpstr_cli_echoall(FILE *, int, struct sockaddr *, socklen_t); int main(int argc, char **argv) { int sock_fd; char *byemsg; struct sockaddr_in servaddr; struct sctp_event_subscribe evnts; int echo_to_all=0; if(argc < 2) { err_quit("Missing host argument - use '%s host [echo]' ",argv[0]); } if(argc > 2) { printf("Echoing messages to all streams "); echo_to_all = 1; } sock_fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERV_PORT); inet_pton(AF_INET, argv[1], &servaddr.sin_addr); bzero(&evnts, sizeof(evnts)); evnts.sctp_data_io_event = 1; setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS,&evnts, sizeof(evnts)); if(echo_to_all == 0) { sctpstr_cli(stdin, sock_fd, (SA *)&servaddr, sizeof(servaddr)); } else { sctpstr_cli_echoall(stdin, sock_fd, (SA *)&servaddr, sizeof(servaddr)); } close(sock_fd); return(0); } void sctpstr_cli(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen) { struct sockaddr_in peeraddr; struct sctp_sndrcvinfo sri; char sendline[MAXLINE], recvline[MAXLINE]; socklen_t len; int out_sz,rd_sz; int msg_flags; bzero(&sri,sizeof(sri)); while (fgets(sendline, MAXLINE, fp) != NULL) { if(sendline[0] != '[' && sendline[2] != ']') { printf("Error, line must be of the form '[streamnum]text' "); continue; } sri.sinfo_stream = strtol(&sendline[1],NULL,0); out_sz = strlen(sendline); int d = sctp_sendmsg(sock_fd, sendline, out_sz, to, tolen, 0, 0, sri.sinfo_stream, 0, 0); printf("d = %d ", d); len = sizeof(peeraddr); rd_sz = sctp_recvmsg(sock_fd, recvline, sizeof(recvline), (SA *)&peeraddr, &len, &sri,&msg_flags); printf("rd_sz = %d ", rd_sz); printf("From str:%d seq:%d (assoc:0x%x):", sri.sinfo_stream,sri.sinfo_ssn, (u_int)sri.sinfo_assoc_id); printf("%.*s",rd_sz,recvline); } } void sctpstr_cli_echoall(FILE *fp, int sock_fd, struct sockaddr *to, socklen_t tolen) { struct sockaddr_in peeraddr; struct sctp_sndrcvinfo sri; char sendline[SCTP_MAXLINE], recvline[SCTP_MAXLINE]; socklen_t len; int rd_sz,i,strsz; int msg_flags; bzero(sendline,sizeof(sendline)); bzero(&sri,sizeof(sri)); while (fgets(sendline, SCTP_MAXLINE - 9, fp) != NULL) { strsz = strlen(sendline); if(sendline[strsz-1] == ' ') { sendline[strsz-1] = '