免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2312 | 回复: 0
打印 上一主题 下一主题

sctp连接例子 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-01-05 09:51 |只看该作者 |倒序浏览
---------server.c------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define M3UA_BUFSIZ 4096
#define MAX_ASSOC 16
enum Ctype{
    SERVER,
    CLIENT
};
static enum Ctype type;
static bool is_stopped = false;
static unsigned short localport;
static fd_set rfd;
static int maxfd = 0;    //max associate fd + 1
static int lissock;
static vector accSock;
void printMSG(unsigned char buf[], int msglen)
{
    printf("0000 | ");
    for (int idx = 0; idx != msglen; ++idx)
        printf("%02x ", buf[idx]);
    printf("\n");
}
int HandleRecv(void)
{
    int flags;
    size_t fromlen;
    struct sockaddr_in from;
    struct sctp_sndrcvinfo sinfo;
    static unsigned char  buf[M3UA_BUFSIZ];
    int msglen = 0;
    for (vector::iterator it = accSock.begin(); it != accSock.end();)
    {
        if ((*it > 0) && (FD_ISSET(*it, &rfd)))
        {
            fromlen = sizeof(fromlen);
            bzero(&from, sizeof(from));
            bzero(&sinfo, sizeof(sinfo));
            if ((msglen = sctp_recvmsg(*it, buf, sizeof(buf), (struct sockaddr* )(&from), &fromlen, &sinfo, &flags))  0) && FD_ISSET(lissock, &rfd))
        return HandleNewConnect();
    return HandleRecv();
}
int max(const int mfd, const int fd)
{
    return mfd > (fd + 1) ? mfd : (fd + 1);
}
void reset(void)
{
    FD_ZERO(&rfd);
    if ((lissock > 0) && FD_SET(lissock, &rfd))
        maxfd = max(maxfd, lissock);
    for (vector::const_iterator it = accSock.begin(); it != accSock.end(); ++it)
    {
        if ((*it > 0) && FD_SET(*it, &rfd))
            maxfd = max(maxfd, *it);
    }
}
int HandleRun(char err[])
{
    struct timeval timeout;
    while (!is_stopped)
    {
        timeout.tv_sec = 1;
        timeout.tv_usec = 0;
        reset();
        switch (select(maxfd, &rfd, NULL, NULL, &timeout)){
        case -1:
            strcpy(err, "Process Select unsuccessfully");
            goto execption;
        case 0:
            // time out
            break;
        default:
            if (HandleSelect() == -1)
            {
                type == SERVER ? strcpy(err, "Cannot handle acceptable socket") : strcpy(err, "Remote Peer I/O shutdown OR Occur system failure");
                goto execption;
            }
        }
    }
    return 0;
execption:
    fprintf(stderr, "%s\n", err);
    return -1;
}
bool initialize_server(char err[])
{
    const int on = 1;
    struct sockaddr_in svraddr;
    struct sctp_initmsg initmsg;
    struct sctp_event_subscribe events;
    if (lissock > 0)
        close(lissock);
    if ((lissock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1)
    {
        strcpy(err, "Fail to create socket");
        return false;
    }
    if (setsockopt(lissock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
    {
        strcpy(err, "Fail to setsockopt SO_REUSEADDR");
        return false;
    }
    bzero(&svraddr, sizeof(svraddr));
    svraddr.sin_family = AF_INET;
    svraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    svraddr.sin_port = htons(localport);
    if (bind(lissock, (struct sockaddr* )(&svraddr), sizeof(svraddr)) == -1)
    {
        strcpy(err, "Fail to bind locale address");
        return false;
    }
    /* Specify that a maximum of 64 streams will be available per socket */
    bzero(&initmsg, sizeof(initmsg));
    initmsg.sinit_num_ostreams = 64;
    initmsg.sinit_max_instreams = 64;
    initmsg.sinit_max_attempts = 4;
    if (setsockopt(lissock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg)) == -1)
    {
        strcpy(err, "Fail to setsockopt SCTP_INITMSG");
        return false;
    }
    /* Enable receipt of SCTP Snd/Rcv Data via sctp_recvmsg */
    bzero(&events, sizeof(events));
    events.sctp_association_event = 1;
    events.sctp_data_io_event = 1;
    if (setsockopt(lissock, SOL_SCTP, SCTP_EVENTS, (void* )(&events), sizeof(events)) == -1)
    {
        strcpy(err, "Fail to setsockopt SCTP_EVENTS");
        return false;
    }
    /* Come into listening state */
    if (listen(lissock, MAX_ASSOC) == -1)
    {
        strcpy(err, "Fail to get into listening");
        return false;
    }
    maxfd = max(maxfd, lissock);
    return true;
}
void setLocalport(const unsigned short lport)
{
    localport = lport;
}
void setCType(const enum Ctype t)
{
    type = t;
}
static void* routine(void* not_used)
{
    pthread_detach(pthread_self());
    void* ret = (void*)0x0;
    char pmsg[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa};
    int msglen = sizeof(pmsg) / sizeof(*pmsg);
    unsigned short streamId = 16;
    while (!is_stopped)
    {
        for (vector::const_iterator it = accSock.begin(); it != accSock.end(); ++it)
        {
            if (sctp_sendmsg(*it, pmsg, msglen, NULL, 0, 0, 0, streamId, 0, 0) != msglen)
            {
                cerr
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define M3UA_BUFSIZ 4096
#define MAX_ASSOC 16
enum Ctype{
    SERVER,
    CLIENT
};
static enum Ctype type;
static bool is_stopped = false;
static char remoteip[20];
static unsigned short remoteport;
static int connsock = -1;
static fd_set rfd;
static int maxfd = 0;    //max associate fd + 1
void printMSG(unsigned char buf[], int msglen)
{
    printf("0000 | ");
    for (int idx = 0; idx != msglen; ++idx)
        printf("%02d ", buf[idx]);
    printf("\n");
}
int HandleRecv(void)
{
    int flags;
    size_t fromlen;
    struct sockaddr_in from;
    struct sctp_sndrcvinfo sinfo;
    static unsigned char  buf[M3UA_BUFSIZ];
    int msglen = 0;
    if ((connsock > 0) && FD_ISSET(connsock, &rfd))
    {
        fromlen = sizeof(fromlen);
        bzero(&from, sizeof(from));
        bzero(&sinfo, sizeof(sinfo));
        if ((msglen = sctp_recvmsg(connsock, buf, sizeof(buf), (struct sockaddr* )(&from), &fromlen, &sinfo, &flags))  (fd + 1) ? mfd : (fd + 1);
}
void reset(void)
{
    FD_ZERO(&rfd);
    if ((connsock > 0) && FD_SET(connsock, &rfd))
        maxfd = max(maxfd, connsock);
}
int HandleRun(char err[])
{
    struct timeval timeout;
    while (!is_stopped)
    {
        timeout.tv_sec = 1;
        timeout.tv_usec = 0;
        reset();
        switch (select(maxfd, &rfd, NULL, NULL, &timeout)){
        case -1:
            strcpy(err, "Process Select unsuccessfully");
            goto execption;
        case 0:
            // time out
            break;
        default:
            if (HandleSelect() == -1)
            {
                type == SERVER ? strcpy(err, "Cannot handle acceptable socket") : strcpy(err, "Remote Peer I/O shutdown OR Occur system failure");
                goto execption;
            }
        }
    }
    return 0;
execption:
    fprintf(stderr, "%s\n", err);
    return -1;
}
bool initialize_client(char err[])
{
    const int on = 1;
    struct sockaddr_in svraddr;
    struct sctp_initmsg initmsg;
    struct sctp_event_subscribe events;
    if (connsock > 0)
        close(connsock);
    if ((connsock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1)
    {
        strcpy(err, "Fail to create socket");
        return false;
    }
    if (setsockopt(connsock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
    {
        strcpy(err, "Fail to setsockopt SO_REUSEADDR");
        return false;
    }
    bzero(&svraddr, sizeof(svraddr));
    svraddr.sin_family = AF_INET;
    svraddr.sin_addr.s_addr = inet_addr(remoteip);
    svraddr.sin_port = htons(remoteport);
    /* Specify that a maximum of 64 streams will be available per socket */
    bzero(&initmsg, sizeof(initmsg));
    initmsg.sinit_num_ostreams = 64;
    initmsg.sinit_max_instreams = 64;
    initmsg.sinit_max_attempts = 4;
    if (setsockopt(connsock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg)) == -1)
    {
        strcpy(err, "Fail to setsockopt SCTP_INITMSG");
        return false;
    }
    /* Enable receipt of SCTP Snd/Rcv Data via sctp_recvmsg */
    bzero(&events, sizeof(events));
    events.sctp_association_event = 1;
    events.sctp_data_io_event = 1;
    if (setsockopt(connsock, SOL_SCTP, SCTP_EVENTS, (void* )(&events), sizeof(events)) == -1)
    {
        strcpy(err, "Fail to setsockopt SCTP_EVENTS");
        return false;
    }
    if (connect(connsock, (struct sockaddr* )(&svraddr), sizeof(svraddr)) == -1)
    {
        strcpy(err, "Fail to connect remote address");
        return false;
    }
    maxfd = max(maxfd, connsock);
    return true;
}
void setRemoteip(const char* rip)
{
    strcpy(remoteip, rip);
}
void setRemoteport(const unsigned short rport)
{
    remoteport = rport;
}
void setCType(const enum Ctype t)
{
    type = t;
}
static void* routine(void* not_used)
{
    pthread_detach(pthread_self());
    void* ret = (void*)0x0;
    char pmsg[] = {0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1};
    int msglen = sizeof(pmsg) / sizeof(*pmsg);
    unsigned short streamId = 0x11;
    while (!is_stopped)
    {
        if ((connsock > 0) && (sctp_sendmsg(connsock, pmsg, msglen, NULL, 0, 0, 0, streamId, 0, 0) != msglen))
        {
            cerr << "Cannot send message, Possibly remote peer shutdown" << endl;
            ret = (void*)0x1;
            break;
        }
        sleep(1);
    }
    pthread_detach(pthread_self());
    return ret;
}
#ifndef NTEST
int main(int argc, char** argv)
{
    char err[128];
    setRemoteip("127.0.0.1");
    setRemoteport(15000);
    setCType(CLIENT);
    pthread_t pid;
    if (pthread_create(&pid, NULL, routine, NULL) != 0)
    {
        cerr << "Create pthread Unsuccessfully" << endl;
        return -1;
    }
    if (initialize_client(err) != true)
    {
        fprintf(stderr, "Fail to initialize server: %s\n", err);
        return -1;
    }
    if (HandleRun(err) == -1)
    {
        fprintf(stderr, "Fail to run recv/send: %s\n", err);
        return -1;
    }
    cout << "Hello world" << endl;
    return 0;
}
#endif //NTEST
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/101003/showart_2139687.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP