OpenRTMFP/Cumulus开发笔记(8) Cumulus服务器端处理高并发连接实例

一.服务器地址的相关初始化,如下:

void HighConcurrentServer::initServerAddr(){
    std::string localAddr = "YOUR_SERVER_IP_ADDR";//这里要填写服务器IP地址,其他都是相关的socket编程的知识
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = ::inet_addr(localAddr.c_str());
    serverAddr.sin_port = htons(SERV_PORT);
}

void HighConcurrentServer::createSocket(){
    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    setnonblocking(listenfd);
    epAdd(listenfd);
    bind(listenfd, (sockaddr *)&serverAddr, sizeof(serverAddr));
    listen(listenfd, MAX_CONNECTOR);
}

二.客户端连接事件的监听,如下:

void HighConcurrentServer::connectHandle(){
    int n = -1;
    n = epoll_wait(connfd, events, MAXEVENTS, 0);
    int sockfd = 0;
    socklen_t clilen;
    for(int i=0;i<n;++i){
        if(events[i].data.fd == listenfd){
            printf("connectHandle()\n");
            sockfd = accept(listenfd, (sockaddr *)&clientAddr, &clilen);
            if(sockfd < 0){
                printf("connfd < 0\n");
                exit(1);
            }
            setnonblocking(sockfd);//设置为非阻塞
            printf("sockfd->%d\n", sockfd);
            char *str = inet_ntoa(clientAddr.sin_addr);
            printf("connect from %s\n", str);
            evt.data.fd = sockfd;
            evt.events = EPOLLIN | EPOLLET;
            epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &evt);
        }
    }
}

说明:这里只是简单地示意了相关过程,没有写实际的业务处理,这个需要根据具体需要开发。

三.非阻塞函数的实现,如下:

void HighConcurrentServer::setnonblocking(int& sockfd) {
    int flags = 0;
    if (-1 == (flags = ::fcntl(sockfd, F_GETFL, 0))) {
        printf("fcntl get flags failed\n");
        exit(1);
    }
    if (-1 == ::fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)) {
        printf("fcntl set sockfd nonblock failed\n");
        exit(1);
    }
}

说明:相关函数的调用,简单明了,无需再详述。

四.接收客户端发送过来的数据,如下:

void HighConcurrentServer::readHandle(){
    int n = -1;
    n = epoll_wait(epfd, events, MAXEVENTS, 0);
    int sockfd = 0;
    socklen_t clilen;
    for(int i=0;i<n;++i){
        if (events[i].events & EPOLLIN) {
            printf("readHandle()\n");
            if ((sockfd = events[i].data.fd) < 0){
                printf("something wrong must happen\n");
                continue;
            }
            if ((n = read(sockfd, dataIn, DATALEN)) < 0) {//读取数据,存储在一个字符数组中,仅示意用,可以自己实现数据的全部读取,也可自己实现缓冲的大小
                if (errno == ECONNRESET) {
                    close (sockfd);
                    events[i].data.fd = -1;
                } else {
                    printf("readline error\n");
                }
            } else if (n = 0) {
                close (sockfd);
                events[i].data.fd = -1;
            } else{
                printf("recv msg is %s",dataIn);
            }
            evt.data.fd = sockfd;
            evt.events = EPOLLOUT | EPOLLET;
            epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &evt);//简单的把用户发过来的数据原样地发回给客户端
        }
    }
}

五.给客户端发送数据,如下:

void HighConcurrentServer::writeHandle(){
    int n = -1;
    n = epoll_wait(epfd, events, MAXEVENTS, 0);
    int sockfd = 0;
    socklen_t clilen;
    for(int i=0;i<n;++i){
        if (events[i].events & EPOLLOUT) {
            printf("writeHandle()\n");
            sockfd = events[i].data.fd;
            write(sockfd, dataIn, DATALEN);
            evt.data.fd = sockfd;
            evt.events = EPOLLIN | EPOLLET;
            epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &evt);
        }
    }
}

源码部分就不上传了,需要的话,可以私下~

PS:初写文章,文笔生涩之处,各位请见谅,若有疑问或者交流的,可加本人YY号:301558660

转载请注明出处:山水间博客,http://blog.csdn.net/linyanwen99/article/details/8195839



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值