今天就跟大家聊聊有关SCTP一对多模式的服务器端代码怎么写,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
以下源码是基于linux操作系统的。实现了基于SCTP协议的一对多模式的服务器端代码,该段不但处理的用户数据,而且处理了的通知类的消息,即notification消息。
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/sctp.h> #include <arpa/inet.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> static void handle_event(void *buf) { struct sctp_assoc_change *sac; struct sctp_send_failed *ssf; struct sctp_paddr_change *spc; struct sctp_remote_error *sre; struct sctp_shutdown_event *sse; union sctp_notification *snp; snp = (sctp_notification*)buf; switch (snp->sn_header.sn_type) { case SCTP_ASSOC_CHANGE: { sac = &snp->sn_assoc_change; printf("assoc_change: state=%hu, error=%hu, instr=%hu outstr=%hu associd=%d\n", sac->sac_state, sac->sac_error, sac->sac_inbound_streams, sac->sac_outbound_streams, sac->sac_assoc_id); break; } case SCTP_SEND_FAILED: { ssf = &snp->sn_send_failed; printf("sendfailed: len=%hu err=%d assoc_i=%d ssf_data=%d\n", ssf->ssf_length, ssf->ssf_error, ssf->ssf_assoc_id, ssf->ssf_data[0]); break; } case SCTP_PEER_ADDR_CHANGE: { spc = &snp->sn_paddr_change; struct sockaddr_in *sin = (struct sockaddr_in *)&spc->spc_aaddr; char addrbuf[INET6_ADDRSTRLEN]; inet_ntop(AF_INET, &sin->sin_addr, addrbuf, INET6_ADDRSTRLEN); printf("peeraddrchange: %s state=%d, error=%d\n", addrbuf, spc->spc_state, spc->spc_error); break; } case SCTP_REMOTE_ERROR: { sre = &snp->sn_remote_error; printf("remote_error: err=%hu len=%hu\n", ntohs(sre->sre_error), ntohs(sre->sre_length)); break; } case SCTP_SHUTDOWN_EVENT: { sse = &snp->sn_shutdown_event; printf("shutdown event: assoc_id=%d\n", sse->sse_assoc_id); break; } default: { printf("unknown type: %hu\n", snp->sn_header.sn_type); break; } } } int main(int agrc, char* agrv[]) { /* Create a 1-to-many style SCTP socket. */ int fd = -1; if ((fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0) { perror("socket"); exit(1); } /* Enable all notifications and events */ struct sctp_event_subscribe event; event.sctp_data_io_event = 1; event.sctp_association_event = 1; event.sctp_address_event = 1; event.sctp_send_failure_event = 1; event.sctp_peer_error_event = 1; event.sctp_shutdown_event = 1; event.sctp_partial_delivery_event = 1; event.sctp_adaption_layer_event = 1; if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)) != 0) { perror("setevent failed"); exit(1); } /* Configure auto-close timer. */ int timeout = 5; if (setsockopt(fd, IPPROTO_SCTP, SCTP_AUTOCLOSE, &timeout, 4) < 0) { perror("setsockopt SCTP_AUTOCLOSE"); exit(1); } /* Bind the socket to all local addresses. */ struct sockaddr_in sin; bzero((char*)&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(19000); sin.sin_addr.s_addr = inet_addr("192.168.10.120"); if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { perror("bind"); exit(1); } /* Enable accepting associations. */ if (listen(fd, 1) < 0) { perror("listen"); exit(1); } char buffer[256]; int bufferlen = 256; bzero(buffer, bufferlen); struct sockaddr_in clientaddr; int fromlen = sizeof(clientaddr); struct sctp_sndrcvinfo sndrcvinfo; int msg_flag; while(true) { int length = sctp_recvmsg(fd, buffer, bufferlen, (struct sockaddr*)&clientaddr, (socklen_t*)&fromlen, &sndrcvinfo, &msg_flag); if (msg_flag & MSG_NOTIFICATION) { printf("****************************************************\n"); printf("Event: notificaiton length=%d\n", length); handle_event((void*)buffer); } else { printf("****************************************************\n"); printf("Event: data event length=%d\n", length); char addrbuf[100]; inet_ntop(AF_INET, &clientaddr.sin_addr, addrbuf, INET6_ADDRSTRLEN); int port = ntohs(clientaddr.sin_port); printf("data from=%s:%d\n", addrbuf, port); printf("data=%s\n", buffer); } } if (close(fd) < 0) { perror("close"); exit(1); } return (0); }
看完上述内容,你们对SCTP一对多模式的服务器端代码怎么写有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。