栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

SCTP多宿主

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SCTP多宿主

好的,我终于解决了多宿主问题。这就是我所做的。

我使用sctp_paddrparams结构将心跳值调整为5000
ms。位于该结构中的flags变量必须处于SPP_HB_ENABLE模式下,因为否则,当尝试使用setsockopt()设置值时,SCTP会忽略心跳值。

这就是SCTP不能像我所希望的那样频繁发送心跳的原因。我没注意到flag变量的原因是我正在阅读的SCTP的过时参考指南,该指南指出该结构内不存在flags变量!较新的参考资料显示存在。这样心跳问题就解决了!

另一件事是将rto_max值修改为例如2000毫秒左右。降低该值将指示SCTP更快地更改路径。默认值为60 000
ms,该值过高(开始更改路径前1分钟)。可以使用sctp_rtoinfo结构调整rto_max值。

通过这两个修改,多宿主开始工作。哦,另一件事。当服务器处于SEQPACKET模式时,客户端必须处于STREAM模式。客户端使用普通的send()命令将数据发送到服务器,而服务器使用sctp_recvmsg()读取数据,其中addr
struct设置为NULL。

我希望这些信息可以帮助其他在SCTP多宿主方面苦苦挣扎的人。欢呼大家的意见,对我来说是很大的帮助!这是一些代码示例,因此如果您问我,这可能是网络中的第一个多宿主简单示例(除了多流示例外,没有找到其他示例)

服务器:

#include <sys/types.h>#include <sys/socket.h>#include <signal.h>#include <netinet/in.h>#include <netinet/sctp.h>#include <arpa/inet.h>#include <string.h>#include <unistd.h>#include <stdio.h>#include <sys/ioctl.h>#include <net/if.h>#include <stdlib.h>#include <pthread.h>#define BUFFER_SIZE (1 << 16)#define PORT 10000int sock, ret, flags;int i, reuse = 1;int addr_count = 0;char buffer[BUFFER_SIZE];socklen_t from_len;struct sockaddr_in addr;struct sockaddr_in *laddr[10];struct sockaddr_in *paddrs[10];struct sctp_sndrcvinfo sinfo;struct sctp_event_subscribe event;  struct sctp_prim prim_addr; struct sctp_paddrparams heartbeat;struct sigaction sig_handler;struct sctp_rtoinfo rtoinfo;void handle_signal(int signum);int main(void){    if((sock = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0)        perror("socket");    memset(&addr,       0, sizeof(struct sockaddr_in));    memset(&event,      1, sizeof(struct sctp_event_subscribe));    memset(&heartbeat,  0, sizeof(struct sctp_paddrparams));    memset(&rtoinfo,    0, sizeof(struct sctp_rtoinfo));    addr.sin_family = AF_INET;    addr.sin_addr.s_addr = htonl(INADDR_ANY);    addr.sin_port = htons(PORT);    from_len = (socklen_t)sizeof(struct sockaddr_in);    sig_handler.sa_handler = handle_signal;    sig_handler.sa_flags = 0;    heartbeat.spp_flags = SPP_HB_ENABLE;    heartbeat.spp_hbinterval = 5000;    heartbeat.spp_pathmaxrxt = 1;    rtoinfo.srto_max = 2000;        if(setsockopt(sock, SOL_SCTP, SCTP_PEER_ADDR_PARAMS , &heartbeat, sizeof(heartbeat)) != 0)        perror("setsockopt");        if(setsockopt(sock, SOL_SCTP, SCTP_RTOINFO , &rtoinfo, sizeof(rtoinfo)) != 0)        perror("setsockopt");        if(sigaction(SIGINT, &sig_handler, NULL) == -1)        perror("sigaction");        if(setsockopt(sock, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)) < 0)        perror("setsockopt");        if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int))< 0)        perror("setsockopt");        if(bind(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr)) < 0)        perror("bind");    if(listen(sock, 2) < 0)        perror("listen");        i = (sizeof heartbeat);    getsockopt(sock, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, &heartbeat, (socklen_t*)&i);    printf("Heartbeat interval %dn", heartbeat.spp_hbinterval);        addr_count = sctp_getladdrs(sock, 0, (struct sockaddr**)laddr);    printf("Addresses binded: %dn", addr_count);    for(i = 0; i < addr_count; i++)         printf("Address %d: %s:%dn", i +1, inet_ntoa((*laddr)[i].sin_addr), (*laddr)[i].sin_port);    sctp_freeladdrs((struct sockaddr*)*laddr);    while(1)    {        flags = 0;        ret = sctp_recvmsg(sock, buffer, BUFFER_SIZE, NULL, 0, NULL, &flags);        if(flags & MSG_NOTIFICATION)        printf("Notification received from %s:%un",  inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));        printf("%d bytes received from %s:%un", ret, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));          }    if(close(sock) < 0)        perror("close");}void handle_signal(int signum){    switch(signum)    {        case SIGINT: if(close(sock) != 0)     perror("close"); exit(0); break;          default: exit(0); break;    }}

客户:

#include <sys/types.h>#include <sys/socket.h>#include <signal.h>#include <netinet/in.h>#include <netinet/sctp.h>#include <arpa/inet.h>#include <string.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <sys/ioctl.h>#define PORT 11000#define MSG_SIZE 1000#define NUMBER_OF_MESSAGES 1000int sock;struct sockaddr_in *paddrs[5];struct sockaddr_in *laddrs[5];void handle_signal(int signum);int main(int argc, char **argv){    int i;    int counter = 0;    int asconf = 1;    int ret;    int addr_count;    char address[16];    char buffer[MSG_SIZE];    sctp_assoc_t id;    struct sockaddr_in addr;    struct sctp_status status;    struct sctp_initmsg initmsg;    struct sctp_event_subscribe events;    struct sigaction sig_handler;    struct sctp_paddrparams heartbeat;    struct sctp_rtoinfo rtoinfo;    memset(&buffer,     'j', MSG_SIZE);    memset(&initmsg,    0,   sizeof(struct sctp_initmsg));    memset(&addr,       0,   sizeof(struct sockaddr_in));    memset(&events,     1,   sizeof(struct sctp_event_subscribe));    memset(&status,     0,   sizeof(struct sctp_status));    memset(&heartbeat,  0,   sizeof(struct sctp_paddrparams));    memset(&rtoinfo,    0, sizeof(struct sctp_rtoinfo))    if(argc != 2 || (inet_addr(argv[1]) == -1))    {        puts("Usage: client [IP ADDRESS in form xxx.xxx.xxx.xxx] ");     return 0;    }    strncpy(address, argv[1], 15);    address[15] = 0;    addr.sin_family = AF_INET;    inet_aton(address, &(addr.sin_addr));    addr.sin_port = htons(PORT);    initmsg.sinit_num_ostreams = 2;    initmsg.sinit_max_instreams = 2;    initmsg.sinit_max_attempts = 1;    heartbeat.spp_flags = SPP_HB_ENABLE;    heartbeat.spp_hbinterval = 5000;    heartbeat.spp_pathmaxrxt = 1;    rtoinfo.srto_max = 2000;    sig_handler.sa_handler = handle_signal;    sig_handler.sa_flags = 0;        if(sigaction(SIGINT, &sig_handler, NULL) == -1)        perror("sigaction");        if((ret = (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP))) < 0)        perror("socket");        if((ret = setsockopt(sock, SOL_SCTP, SCTP_PEER_ADDR_PARAMS , &heartbeat, sizeof(heartbeat))) != 0)        perror("setsockopt");        if((ret = setsockopt(sock, SOL_SCTP, SCTP_RTOINFO , &rtoinfo, sizeof(rtoinfo))) != 0)        perror("setsockopt");        if((ret = setsockopt(sock, SOL_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg))) != 0)        perror("setsockopt");        if((ret = setsockopt(sock, SOL_SCTP, SCTP_EVENTS, (void *)&events, sizeof(events))) != 0)        perror("setsockopt");        i = (sizeof heartbeat);    getsockopt(sock, SOL_SCTP, SCTP_PEER_ADDR_PARAMS, &heartbeat, (socklen_t*)&i);    printf("Heartbeat interval %dn", heartbeat.spp_hbinterval);        if(((ret = connect(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr)))) < 0)    {        perror("connect");        close(sock);        exit(0);    }        addr_count = sctp_getpaddrs(sock, 0, (struct sockaddr**)paddrs);    printf("nPeer addresses: %dn", addr_count);        for(i = 0; i < addr_count; i++)        printf("Address %d: %s:%dn", i +1, inet_ntoa((*paddrs)[i].sin_addr), (*paddrs)[i].sin_port);    sctp_freepaddrs((struct sockaddr*)*paddrs);        for(i = 0; i < NUMBER_OF_MESSAGES; i++)    {        counter++;        printf("Sending data chunk #%d...", counter);        if((ret = send(sock, buffer, MSG_SIZE, 0)) == -1) perror("write");        printf("Sent %d bytes to peern",ret);        sleep(1);    }    if(close(sock) != 0)        perror("close");}void handle_signal(int signum){    switch(signum)    {        case SIGINT: if(close(sock) != 0)     perror("close"); exit(0); break;          default: exit(0); break;    }}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/403334.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号