linux的select实例

我用set存储文件描述符,复杂度会更高。

如果用vector管理所有文件描述符的话,一个描述符连接关闭删除复杂度较高。用set在Log复杂度删除,感觉更方便一点。

复杂度更低的一个思路:
开辅助数组/Vector存,再开一个数组存标志位(是否连接)。

//复用服务器
#include <unp.h>
#include <iostream>
#include <set>
#include <functional>
#include <math.h>
using namespace std;
using namespace placeholders;
typedef void (*func)(int,int);
int main(){
    int m_socket=socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(60000);
    // cout<<addr.sin_port<<endl;
    addr.sin_addr.s_addr=htonl(INADDR_ANY);
    int tlen=1;
    if(setsockopt(m_socket,SOL_SOCKET,SO_REUSEADDR,&tlen,sizeof(tlen))<0){
        perror("setsocket error"); exit(-1);
    }
    if(bind(m_socket,(SA*)&addr,sizeof(addr))<0){
        perror("bind error"); exit(-1);
    }
    if(listen(m_socket,10)<0){
        perror("listen error"); exit(-1);
    }
    int maxfd=0;
    fd_set allfd;
    timeval timeout{3,0};
    set<int> s;
    s.insert(m_socket);
    while(1){
        int now;
        FD_ZERO(&allfd);
        for(auto i:s){
            FD_SET(i,&allfd);
            maxfd=max(maxfd,i+1);
        }
        switch(now=select(maxfd,&allfd,NULL,NULL,NULL)){
            case -1: perror("select error"); exit(-1);
            case 0: break;
            default:
                if(FD_ISSET(m_socket,&allfd)){
                    int d_socket=accept(m_socket,NULL,NULL);
                    if(d_socket<0){
                        perror("accept error"); exit(-1);
                    }
                    cout<<d_socket<<"  连接成功 "<<endl;
                    s.insert(d_socket);
                    maxfd=max(maxfd,d_socket+1);
                }
                for(auto i:s){
                    if(i==m_socket) continue;
                    if(FD_ISSET(i,&allfd)){
                        cout<<i<<"  有数据到 "<<endl;
                        char buf[1024];
                        int len=recv(i,buf,sizeof(buf)-1,0);
                        if(len==0){
                            FD_CLR(i,&allfd);
                            cout<<i<<"  关闭连接 "<<endl;
                            s.erase(i);
                            close(i);
                        }
                        else if(len<0){
                            perror("recv error"); exit(-1);
                        }
                        else{
                            buf[len]='\0';
                            cout<<buf<<endl;
                        }
                    }
                }
        }
        // cout<<now<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值