• SCTP一到多式流分回射服程序


    一、服务器程序

    #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] = '';
                strsz--;
            }
            for(i=0;i<SERV_MAX_SCTP_STRM;i++) {
                snprintf(sendline + strsz, sizeof(sendline) - strsz,
                    ".msg.%d", i);
                sctp_sendmsg(sock_fd, sendline, sizeof(sendline), 
                         to, tolen, 
                         0, 0,
                         i,
                         0, 0);
            }
            for(i=0;i<SERV_MAX_SCTP_STRM;i++) {
                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);
            }
        }
    }
    #include    <stdio.h>
    #include    <errno.h>
    #include    <stdlib.h>
    #include    <string.h>
    #include    <stdarg.h>        /* ANSI C header file */
    #include    <syslog.h>        /* for syslog() */
    
    #define     MAXLINE     4096
    
    int        daemon_proc;       /* set nonzero by daemon_init() */
    
    static void    err_doit(int, int, const char *, va_list);
    
    /* Nonfatal error related to system call
     * Print message and return */
    
    void err_ret(const char *fmt, ...) {
    
        va_list        ap;    
    
        va_start(ap, fmt);    
        err_doit(1, LOG_INFO, fmt, ap);
        va_end(ap);
        return;
    }
    
    /* Fatal error related to system call
     * Print message and terminate */
    
    void err_sys(const char *fmt, ...) {
    
        va_list        ap;
    
        va_start(ap, fmt);
        err_doit(1, LOG_ERR, fmt, ap);
        va_end(ap);
        exit(1);
    }
    
    /* Fatal error related to system call
     * Print message, dump core, and terminate */
    
    void err_dump(const char *fmt, ...) {
        va_list        ap;
    
        va_start(ap, fmt);
        err_doit(1, LOG_ERR, fmt, ap);
        va_end(ap);
        abort();        /* dump core and terminate */
        exit(1);        /* shouldn't get here */
    }
    
    /* Nonfatal error unrelated to system call
     * Print message and return */
    
    void err_msg(const char *fmt, ...) {
    
        va_list        ap;
    
        va_start(ap, fmt);
        err_doit(0, LOG_INFO, fmt, ap);
        va_end(ap);
        return;
    }
    
    /* Fatal error unrelated to system call
     * Print message and terminate */
    
    void err_quit(const char *fmt, ...) {
    
        va_list        ap;
    
        va_start(ap, fmt);
        err_doit(0, LOG_ERR, fmt, ap);
        va_end(ap);
        exit(1);
    }
    
    /* Print message and return to caller
     * Caller specifies "errnoflag" and "level" */
    
    static void err_doit(int errnoflag, int level, const char *fmt, va_list ap) {
    
        int        errno_save, n;
        char    buf[MAXLINE + 1];
    
        errno_save = errno;                /* value caller might want printed */
    #ifdef    HAVE_VSNPRINTF
        vsnprintf(buf, MAXLINE, fmt, ap);  /* safe */
    #else
        vsprintf(buf, fmt, ap);            /* not safe */
    #endif
        n = strlen(buf);
        if (errnoflag)
            snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save));
        strcat(buf, "
    ");
    
        if (daemon_proc) {
            syslog(level, buf);
        } else {
            fflush(stdout);                /* in case stdout and stderr are the same */
            fputs(buf, stderr);
            fflush(stderr);
        }
        return;
    }
  • 相关阅读:
    nodejs
    flask中flash(闪现)的使用
    flask中logger日志的使用
    flask中session的使用
    flask开启调试模式
    flask中静态文件的引入
    flask中模板引入
    python web开发屠龙刀flask
    python操作excel基础1-环境搭建
    php算法-dijkstra
  • 原文地址:https://www.cnblogs.com/soldierback/p/10744283.html
Copyright © 2020-2023  润新知