SCTP 回显C/S

服务端代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/sctp.h>
#include <string.h>
#include <errno.h>

#define BUFSIZE 4096
#define PORT 6007
#define LISTENQ 100
#define SCTP_MAX_STREAM 15

int main(int argc,char **argv) {
    int sockfd,msg_flags;
    char readbuf[BUFSIZE + 1];
    struct sockaddr_in serveraddr,clientaddr;
    struct sctp_sndrcvinfo sri;
    struct sctp_event_subscribe events;
    int stream_increment = 1;
    socklen_t len;
    size_t rd_sz;

    if (argc == 2)
        stream_increment = atoi(argv[1]);

    if ((sockfd = socket(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP)) < 0) {
        printf("sockfd error %s\n",strerror(errno));
        exit(1);
    }
    struct sctp_initmsg sim;
    bzero(&sim,sizeof(struct sctp_initmsg));
    sim.sinit_num_ostreams = SCTP_MAX_STREAM;

    if (setsockopt(sockfd,IPPROTO_SCTP,SCTP_INITMSG,&sim,sizeof(struct sctp_initmsg)) < 0) {
        printf("setsockopt error: %s\n",strerror(errno));
        exit(1);
    }
    bzero(&serveraddr,sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(PORT);
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr)) < 0) {
        printf("bind error %s\n",strerror(errno));
        exit(1);
    }

    bzero(&events,sizeof(events));
    events.sctp_data_io_event = 1;

    if (setsockopt(sockfd,IPPROTO_SCTP,SCTP_EVENTS,&events,sizeof(events)) < 0) {
        printf("setsockopt error %s\n",strerror(errno));
        exit(1);
    }

    if (listen(sockfd,LISTENQ) < 0) {
        printf("listen error %s\n",strerror(errno));
        exit(1);
    }

    for (; ;) {
        len = sizeof(struct sockaddr_in);
        if ((rd_sz = sctp_recvmsg(sockfd,readbuf,sizeof(readbuf),(struct sockaddr*)&clientaddr,&len,&sri,&msg_flags)) < 0) {
            printf("sctp_recvmsg error %s\n",strerror(errno));
            exit(1);
        }
        if (stream_increment) {
            sri.sinfo_stream++;
            if (sri.sinfo_stream >= SCTP_MAX_STREAM) {

                sri.sinfo_stream = 0;

            }
        }

        if (sctp_sendmsg(sockfd,readbuf,rd_sz,(struct sockaddr*)&clientaddr,len,sri.sinfo_ppid,sri.sinfo_flags,sri.sinfo_stream,0,0) != rd_sz) {
            printf("sctp_sendmsg error %s\n",strerror(errno));
            exit(1);
        }
    }
}

客户端代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <netinet/sctp.h>

#define PORT 6007
#define BUFSIZE 4096
#define SCTP_MAX_STREAM 15

void client_echo_all(int fd,struct sockaddr* to,socklen_t tolen) {
    struct sctp_event_subscribe events;
    bzero(&events,sizeof(struct sctp_event_subscribe));
    events.sctp_data_io_event = 1;
    if (setsockopt(fd,IPPROTO_SCTP,SCTP_EVENTS,&events,sizeof(struct sctp_event_subscribe)) < 0) {
        printf("setsockopt error: %s\n",strerror(errno));
        exit(1);
    }

    struct sctp_initmsg sim;
    bzero(&sim,sizeof(struct sctp_initmsg));
    sim.sinit_num_ostreams = SCTP_MAX_STREAM;
    if (setsockopt(fd,IPPROTO_SCTP,SCTP_INITMSG,&sim,sizeof(struct sctp_initmsg)) < 0) {
        printf("setsockopt error: %s\n",strerror(errno));
        exit(1);
    }
    char sendbuf[BUFSIZE + 1],recvbuf[BUFSIZE + 1];
    int n;
    struct sctp_sndrcvinfo sri;
    socklen_t len = tolen;
    int msg_flags;
    while ((n = read(STDIN_FILENO,sendbuf,BUFSIZE)) > 0) {
        if (sendbuf[n - 1] == '\n') {
            sendbuf[n - 1] = '\0';
            --n;
        }
        for (int i = 0; i < SCTP_MAX_STREAM; ++i) {
            snprintf(sendbuf + n,sizeof(sendbuf) - n,".msg.%d 1",i);
            if (sctp_sendmsg(fd,sendbuf,sizeof(sendbuf),to,tolen,0,0,i,0,0) != sizeof(sendbuf)) {
                printf("sctp_sendmsg error: %s\n",strerror(errno));
                exit(1);
            }
            snprintf(sendbuf + n,sizeof(sendbuf) - n,".msg.%d 2",i);
            if (sctp_sendmsg(fd,sendbuf,sizeof(sendbuf),to,tolen,0,0,i,0,0) != sizeof(sendbuf)) {
                printf("sctp_sendmsg error: %s\n",strerror(errno));
                exit(1);
            }
        }
        for (int i = 0; i < 2 * SCTP_MAX_STREAM; ++i) {
            if ((n = sctp_recvmsg(fd,recvbuf,sizeof(recvbuf),to,&len,&sri,&msg_flags)) < 0) {
                printf("get the message from server failed %s\n",strerror(errno));
                exit(1);
            }
            printf("From stream: %d sequence: %d (assoc:0x%x)",sri.sinfo_stream,sri.sinfo_ssn,(unsigned)sri.sinfo_assoc_id);
            printf("%.*s\n",n,recvbuf);     
        }
    }

}


int main(int argc,char **argv) {

    if (argc != 2) {
        printf("please add <ip address>\n");
        exit(1);
    }
    int sockfd;
    if ((sockfd = socket(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP)) < 0) {
        printf("socket error: %s\n",strerror(errno));
        exit(1);
    }

    struct sockaddr_in serveraddr;
    bzero(&serveraddr,sizeof(struct sockaddr_in));

    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(PORT);
    if (inet_pton(AF_INET,argv[1],&serveraddr.sin_addr) <= 0) {
        printf("inet_pton error: %s\n",strerror(errno));
        exit(1);
    }
    client_echo_all(sockfd,(struct sockaddr*)&serveraddr,sizeof(struct sockaddr));

    return 0;
}

运行:

这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值