UDP并发服务器模型 二:select机制

上篇文章说了下 udp 并发模型。然后笔者也自己编写了一套代码,基本上能显示 udp 并发机制。大致原理参考:
http://blog.csdn.net/aa120515692/article/details/47294335

select机制能很好地提供多路IO功能。对于本套代码,已基本上能提供类似 select 的功能

主要函数接口:

void listen_head_init(struct list_head *head)
初始化一个 链表头

int listen_add(struct list_head *head, listen_t *listen)
将要监听的 listen 添加到这个链表头

recv_from_listen_head
从链表中获取数据

示例:

    //我们创建两个 listen_head 
    struct list_head poll_head_1, poll_head_2;

    int main(int argc, char *argv[])
    {
        int poll_num = 0;
        struct listen *_listen;

        /* 初始化socket */
        sockfd = init_socket(); 

        /*
            开始监听这个socket. 运行最大的连接数为10
            该函数类似于TCP协议中的 int listen(SOCKET sockfd, int backlog)
        */
        server_listen(&sockfd, 10);

        /* 初始化这个poll 机制 */
        listen_head_init(&poll_head_1);
        listen_head_init(&poll_head_2);

        while(1)
        {
            /* 获得一个连接。类似于TCP的
            int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 
            */
            _listen = server_accept();

            if(_listen == NULL){
                continue;
            }

            printf("new client \r\n");

            if(poll_num < 5)
            {
                /* 前面五个连接者添加到 poll_head_1 */
                poll_num ++;
                listen_add(&poll_head_1, _listen);
            }else{
                /* 添加到 poll_head_2 */
                poll_num ++;
                listen_add(&poll_head_2, _listen);
            }
        }
    }
然后我们就可以从中两个 listen_head 中读取数据了
    while(1)
    {
        /*
        从 poll_head_1 中读取数据。
        此时,前面五个 listen 被挂钩到这个 poll_head_1,所以这五个listen中任何一个有了数据
        recv_from_listen_head 都会返回,而且将 _listen 指向这个 listen 
        这样,我们就可以知道是哪个listen有数据了
        */
        ret = recv_from_listen_head(poll_head_1, &_listen, (struct sockaddr *)&clientaddr, buf, 1204, -1);
        if(ret == -1)
        {
            printf("%p recv is err \r\n", _listen);
        }else{
            printf("__ poll %p recv %d byte data is [%s]\r\n", _listen, ret, buf);
            if((ret = sendto(sockfd, buf, ret, 0, (struct sockaddr *)(&(_listen->addr)), 
                                    sizeof(struct sockaddr))) == -1)
            {
                perror("sendto :");
            }
            printf("sento [%s]\r\n", buf);
        }
    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值