zoukankan      html  css  js  c++  java
  • IO复用之select

    select使用的是IO复用的方式进行多客户端的处理,当有客户端的连接以后会将该客户端的套接字等信息添加到队列中,然后采用轮询的方式来判断客户端是否有消息发送过来.如果客户端断开,重置队列信息,关闭套接字.

    因为是使用轮询的方式进行,所以在较多客户端下速度会较慢,而且受到Linux文件描述符的数量的限制,建议在中低并发量中使用.

    同样的select也有一般的形式:

    int main(int argc,char *argv[])
    {
    int listenfd;          //监听套接字
    fd_set current_fds,bak_fds;  //select的队列
    int ret;            //判断返回值是否正确
    int maxfds;          //最大连接数
    int i;              //用于轮询的循环计数
    int fdtmp;           //当前数值最大的套接字,用来减少轮询的数量

    // 创建监听描述符
    listenfd = create_tcp_server(8888);
    if (listenfd < 0) {
    perror("create tcp server failed!");
    exit(-1);
    }

    /*初始化队列*/
    FD_ZERO(&bak_fds);      //初始化队列
    FD_SET(0,&bak_fds);       //初始化队列
    FD_SET(listenfd,&bak_fds);    //将监听套接字放到队列中
    maxfds = listenfd;       //将最大的套接字修改为监听套接字

    //死循环来等待和处理客户端
    while (1){
    current_fds = bak_fds;//保险起见将队列复制一份使用

    ret = select(maxfds+1, &current_fds, NULL, NULL, NULL);//启动select函数
    if (ret < 0) {//判断是否成功
    perror("select:");
    close(listenfd);
    return -1;
    }

    for (i = 0; i <= maxfds; i++) {//轮询
    if( FD_ISSET(i,&current_fds) ){//读取相关的描述符
    if (i == 0) {//标准输入输出
    continue;
    }
    else if( i == listenfd ){//有新连接
    fdtmp = process_listend(listenfd);//处理新连接
    if (fdtmp < 0) {//出错
    fprintf(stderr, "listenfd failed! ");
    break;
    }
    printf("the newfd is %d ",fdtmp);
    FD_SET(fdtmp,&bak_fds);//将新的客户端的描述符加入队列
    if (fdtmp > maxfds) {//更新最大的描述符
    maxfds = fdtmp;
    }
    }
    else{//有信息发送过来
    ret = process_message(i);//处理发送过来的信息
    if (ret == 0) {//客户端断开连接
    FD_CLR(i,&bak_fds);
    close(i);
    }
    }
    }
    }
    }

    }

    int process_listend(int sockfd)
    {
    int newfd;

    newfd = accept(sockfd, NULL, NULL);
    if (newfd < 0) {
    perror("accept");
    return -1;
    }

    printf("have a new connection... ");
    return newfd;
    }

  • 相关阅读:
    redis基本介绍搭建篇
    Percona XtraDB Cluster集群
    path模块
    vue相关
    Vue首页加载过慢 解决方案
    从用户输入url到页面最后呈现 发生了些什么?
    cookie
    javascript中怎么判断对象{}为空
    jquery之stop()的用法
    跨域
  • 原文地址:https://www.cnblogs.com/CHYI1/p/5493017.html
Copyright © 2011-2022 走看看