加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读