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] != '[') { printf("Error, line must be of the from '[streamnum]text'\n"); continue; } sri.sinfo_stream = strtol(&sendline[1], NULL, 0); out_sz = strlen(sendline); Sctp_sendmsg(sock_fd, sendline, out_sz, to, tolen, 0, 0, sri.sinfo_stream, 0, 0); len = sizeof(peeraddr); rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline), (SA *)&peeraddr, &len, &sri, &msg_flags); 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); } }
int main(int argc, char **argv) { int sock_fd,msg_flags,connfd,childpid; sctp_assoc_t assoc; char readbuf[BUFFSIZE]; struct sockaddr_in servaddr, cliaddr; struct sctp_sndrcvinfo sri; struct sctp_event_subscribe evnts; socklen_t len; size_t rd_sz; 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); printf("Start waiting...\n"); /* include mod_servfork */ for ( ; ; ) { len = sizeof(struct sockaddr_in); rd_sz = Sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf), (SA *)&cliaddr, &len, &sri,&msg_flags); Sctp_sendmsg(sock_fd, readbuf, rd_sz, (SA *)&cliaddr, len, sri.sinfo_ppid, sri.sinfo_flags, sri.sinfo_stream, 0, 0); assoc = sctp_address_to_associd(sock_fd,(SA *)&cliaddr,len); if((int)assoc == 0){ err_ret("Can't get association id"); continue; } connfd = sctp_peeloff(sock_fd,assoc); if(connfd == -1){ err_ret("sctp_peeloff fails"); continue; } if((childpid = fork()) == 0) { Close(sock_fd); str_echo(connfd); exit(0); } else { Close(connfd); } } /* end mod_servfork */ }
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)); /* include mod_serv06 */ bzero(&evnts, sizeof(evnts)); evnts.sctp_data_io_event = 1; evnts.sctp_association_event = 1; evnts.sctp_address_event = 1; evnts.sctp_send_failure_event = 1; evnts.sctp_peer_error_event = 1; evnts.sctp_shutdown_event = 1; evnts.sctp_partial_delivery_event = 1; evnts.sctp_adaption_layer_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(msg_flags & MSG_NOTIFICATION) { print_notification(readbuf); continue; } /* end mod_serv06 */ 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 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; struct sctp_initmsg initm; /* include modified_sctpserv02 */ if (argc == 2) stream_increment = atoi(argv[1]); sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); bzero(&initm,sizeof(initm)); initm.sinit_num_ostreams = SERV_MORE_STRMS_SCTP; Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_INITMSG, &initm, sizeof(initm)); /* end modified_sctpserv02 */ 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 main(int argc, char **argv) { int sock_fd,msg_flags; char readbuf[BUFFSIZE]; struct sockaddr_in cliaddr; struct sctp_sndrcvinfo sri; struct sctp_event_subscribe evnts; socklen_t len; size_t rd_sz; /* include mod_serv07 */ if(argc < 2) err_quit("Error, use %s [list of addresses to bind]\n", argv[0]); sock_fd = Socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP); if(sctp_bind_arg_list(sock_fd, argv + 1, argc - 1)) err_sys("Can't bind the address set"); bzero(&evnts, sizeof(evnts)); evnts.sctp_data_io_event = 1; /* end mod_serv07 */ evnts.sctp_association_event = 1; evnts.sctp_address_event = 1; evnts.sctp_send_failure_event = 1; evnts.sctp_peer_error_event = 1; evnts.sctp_shutdown_event = 1; evnts.sctp_partial_delivery_event = 1; evnts.sctp_adaption_layer_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(msg_flags & MSG_NOTIFICATION) { print_notification(readbuf); continue; } Sctp_sendmsg(sock_fd, readbuf, rd_sz, (SA *)&cliaddr, len, sri.sinfo_ppid, sri.sinfo_flags, sri.sinfo_stream, 0, 0); } }
uint8_t * pdapi_recvmsg(int sock_fd, int *rdlen, SA *from, int *from_len, struct sctp_sndrcvinfo *sri, int *msg_flags) { int rdsz,left,at_in_buf; int frmlen=0; if (sctp_pdapi_readbuf == NULL) { sctp_pdapi_readbuf = (uint8_t *)Malloc(SCTP_PDAPI_INCR_SZ); sctp_pdapi_rdbuf_sz = SCTP_PDAPI_INCR_SZ; } at_in_buf = Sctp_recvmsg(sock_fd, sctp_pdapi_readbuf, sctp_pdapi_rdbuf_sz, from, from_len, sri,msg_flags); if(at_in_buf < 1){ *rdlen = at_in_buf; return(NULL); } while((*msg_flags & MSG_EOR) == 0) { left = sctp_pdapi_rdbuf_sz - at_in_buf; if(left < SCTP_PDAPI_NEED_MORE_THRESHOLD) { sctp_pdapi_readbuf = realloc(sctp_pdapi_readbuf, sctp_pdapi_rdbuf_sz+SCTP_PDAPI_INCR_SZ); if(sctp_pdapi_readbuf == NULL) { err_quit("sctp_pdapi ran out of memory"); } sctp_pdapi_rdbuf_sz += SCTP_PDAPI_INCR_SZ; left = sctp_pdapi_rdbuf_sz - at_in_buf; } rdsz = Sctp_recvmsg(sock_fd, &sctp_pdapi_readbuf[at_in_buf], left, NULL, &frmlen, NULL, msg_flags); at_in_buf += rdsz; } *rdlen = at_in_buf; return(sctp_pdapi_readbuf); }
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] == '\n') { sendline[strsz-1] = '\0'; strsz--; } /* include modified_echo */ for(i=0;i<SERV_MAX_SCTP_STRM;i++) { snprintf(sendline + strsz, sizeof(sendline) - strsz, ".msg.%d 1", i); Sctp_sendmsg(sock_fd, sendline, sizeof(sendline), to, tolen, 0, 0, i, 0, 0); snprintf(sendline + strsz, sizeof(sendline) - strsz, ".msg.%d 2", i); Sctp_sendmsg(sock_fd, sendline, sizeof(sendline), to, tolen, 0, 0, i, 0, 0); } for(i=0;i<SERV_MAX_SCTP_STRM*2;i++) { len = sizeof(peeraddr); /* end modified_echo */ rd_sz = Sctp_recvmsg(sock_fd, recvline, sizeof(recvline), (SA *)&peeraddr, &len, &sri,&msg_flags); printf("From str:%d seq:%d (assoc:0x%x):", sri.sinfo_stream,sri.sinfo_ssn, (u_int)sri.sinfo_assoc_id); printf("%.*s\n",rd_sz,recvline); } } }
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; //默认情况下服务器响应所有的流号是在其上接收消息的流号加1 if(argc == 2) stream_increment = atoi(argv[1]); //创建一个SCTP套接字 sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); //捆绑一个地址,在待捆绑到该套接字地址结构中填入通陪地址(INADDR_ANY)和服务器的众所周知端口 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)); //预订感兴趣的通知,服务器修改一到多SCTP套接字的通知预订,服务器查看stcp_sndrcvinfo结构,服务器可从该结构确定消息到达所在的流号 bzero(&evnts, sizeof(evnts)); evnts.stcp_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); //当消息到达时,服务器检查stream_incrment标志变量以确定是否需要增长流号 if(stream_increment){ sri.sinfo_stream++; //如果流号増长到大于等于最大流号,服务器流号置1; if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd, (SA *)&cliaddr, len)) sri.sinfo_stream = 0; } //服务器使用来自sri结构的净荷协议ID,标志, 流号发送回消息本身,MSG_EOF标志促使服务器咋应答消息被客户成功确认之后关闭关联 Sctp_sendmsg(sock_fd, readbuf, rd_sz, (SA*)&cliaddr, len, sri.sinfo_ppid, (sri.sinfo_flags | MSG_EOF), sri.sinfo_stream, 0, 0); } }
int main(int argc,char **argv) { int sock_fd; struct sockaddr_in servaddr,peeraddr; struct sctp_sndrcvinfo sri; struct sctp_event_subscribe evnts; int msg_flags; char readbuf[MAXLINE]; socklen_t len; bzero(&sri,sizeof(sri)); if (argc < 2) { err_quit("Missing host argument - use '%s host'\n",argv[0]); } 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)); // 接收所輸入的指令 while((fgets(readbuf,MAXLINE,stdin)) != NULL) { Sctp_sendmsg(sock_fd,readbuf,strlen(readbuf),(SA *) &servaddr,sizeof(servaddr),0,0,sri.sinfo_stream,0,0); sri.sinfo_stream++; if (sri.sinfo_stream>9) sri.sinfo_stream = 0; bzero(readbuf,MAXLINE); len = sizeof(peeraddr); Sctp_recvmsg(sock_fd,readbuf,MAXLINE,(SA *) &peeraddr,&len,&sri,&msg_flags); printf("%s\n",readbuf); if (strncmp(readbuf,"open ok",strlen("open ok"))) RecvFile(sock_fd,"copy",(SA *) &peeraddr,len,sri.sinfo_stream); } Close(sock_fd); return 0; }