SCTP并发服务器
发布时间:2020-12-15 19:44:19 所属栏目:安全 来源:网络整理
导读:注:一定要通过setsockopt函数开启sctp_io_data_event事件,否则得到的关联号可能为0,从而调用getpeeloff失败 服务器端代码: #include stdio.h #include sys/socket.h #include stdlib.h #include string.h #include errno.h #include netdb.h #include netine
注:一定要通过setsockopt函数开启sctp_io_data_event事件,否则得到的关联号可能为0,从而调用getpeeloff失败 服务器端代码: #include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/sctp.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#define BUFSIZE 4096
#define LISTENQ 100
const char* Inet_ntop(void* ptr) {
static char str[INET_ADDRSTRLEN];
return inet_ntop(AF_INET,ptr,str,INET_ADDRSTRLEN);
}
static void sig_child(int signo) {
int pid;
while ((pid = waitpid(-1,NULL,WNOHANG)) > 0) {
printf("child process %d terminatedn",pid);
}
}
void server_echo(int sockfd) {
struct sctp_sndrcvinfo sri;
struct sockaddr_in clientaddr;
socklen_t len = sizeof(struct sockaddr_in);
int pid;
char buf[BUFSIZE];
ssize_t n;
int connfd;
sctp_assoc_t id;
bzero(&sri,sizeof(struct sctp_sndrcvinfo));
struct sctp_event_subscribe events;
bzero(&events,sizeof(struct sctp_event_subscribe));
events.sctp_data_io_event = 1;
if (setsockopt(sockfd,IPPROTO_SCTP,SCTP_EVENTS,&events,sizeof(struct sctp_event_subscribe)) < 0) {
printf("setsockopt error: %sn",strerror(errno));
exit(1);
}
while ((n = sctp_recvmsg(sockfd,buf,BUFSIZE,(struct sockaddr*)&clientaddr,&len,&sri,&len)) > 0) {
if (sctp_sendmsg(sockfd,n,len,0,2,0) != n) {
printf("sctp_sendmsg error: %sn",strerror(errno));
break;
}
if ((connfd = sctp_peeloff(sockfd,sri.sinfo_assoc_id)) < 0) {
printf("sctp_peeloff error: %sn",strerror(errno));
exit(1);
}
if ((pid = fork()) < 0) {
printf("fork error: %sn",strerror(errno));
exit(1);
}else if (pid == 0) {
char childbuf[BUFSIZE];
ssize_t n;
struct sockaddr_in peer;
socklen_t peerlen = sizeof(struct sockaddr_in);
struct sctp_sndrcvinfo csri;
int cflags;
while ((n = sctp_recvmsg(connfd,childbuf,(struct sockaddr*)&peer,&peerlen,&csri,&cflags)) > 0) {
printf("child process pid = %d from IP: %sn",getpid(),Inet_ntop(&peer.sin_addr));
if (sctp_sendmsg(connfd,peerlen,3,0) != n) {
printf("sctp_sendmsg error: %sn",strerror(errno));
exit(1);
}
}
exit(0);
}
}
}
int main(int argc,char** argv) {
if (argc != 2) {
printf("please add or check <service-name or port>n");
exit(1);
}
struct addrinfo hints;
bzero(&hints,sizeof(struct addrinfo));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_SEQPACKET;
hints.ai_protocol = IPPROTO_SCTP;
struct addrinfo* results;
int err;
if ((err = getaddrinfo(NULL,argv[1],&hints,&results)) != 0) {
printf("getaddrinfo error: %sn",strerror(err));
exit(1);
}
struct addrinfo* dummy = results;
int sockfd;
for (; dummy != NULL; dummy = dummy->ai_next) {
if ((sockfd = socket(dummy->ai_family,dummy->ai_socktype,dummy->ai_protocol)) < 0) {
continue;
}
if (bind(sockfd,dummy->ai_addr,dummy->ai_addrlen) == 0) {
break;
}
close(sockfd);
}
if (dummy == NULL) {
printf("all socket failedn");
freeaddrinfo(results);
exit(1);
}
if (listen(sockfd,LISTENQ) < 0) {
printf("listen error: %sn",strerror(errno));
exit(1);
}
freeaddrinfo(results);
if (signal(SIGCHLD,sig_child) == SIG_ERR) {
printf("signal error: %sn",strerror(errno));
exit(1);
}
server_echo(sockfd);
return 0;
} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
热点阅读