认识IO多路复用(select/poll/epoll)

        IO多路复用可以在一个线程中处理多个文件描述符的读、写、异常事件。将需要处理的文件描述符或者套接字,调用select、poll或者epoll_wait函数就可以委托内核去监听这些文件描述符或者套接字的事件,当事件触发时就能设计相应的处理动作。

一、select

使用select实现TcpServer如下:

        基本流程:准备好一个用于监听的socket_fd(设置套接字,绑定端口,开始监听),将socket_fd加入一个fd_set中,调用select监听,将socket_fd的连接事件添加进监听集合,将其他client_fd的读事件处理,循环往复。

#include <stdio.h>
#include <sys/select.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>

int main()
{
    int socket_fd=socket(AF_INET,SOCK_STREAM,0);

    struct sockaddr_in servaddr;
    servaddr.sin_family=AF_INET;
    servaddr.sin_addr.s_addr=htonl(INADDR_ANY);//0.0.0.0
    servaddr.sin_port=htons(2000);//0-1023

    if(-1==bind(socket_fd,(struct sockaddr*)&servaddr,sizeof(struct sockaddr))){
        printf("bind failed: %s\n",strerror(errno));
    }

    listen(socket_fd,10);
    printf("lisent finished\n");

    fd_set rfds,rset;//一个bit位数组集合 大小为1024
    FD_ZERO(&rfds);
    FD_SET(socket_fd,&rfds);

    int maxfd=socket_fd;//最大fd

    while(1){
        rset=rfds;//监听集合
        int nready=select(maxfd+1,&rset,NULL,NULL,NULL);
        if(FD_ISSET(socket_fd,&rset)){//accept
            struct sockaddr_in client_addr;
            socklen_t len=sizeof(client_addr);
            int client_fd=accept(socket_fd,(struct sockaddr*)&client_addr,&len);

            FD_SET(client_fd,&rfds);
            maxfd=maxfd>client_fd?maxfd:client_fd;//更新最大fd
        }
        //recv
        int i=0;
        for(i=socket_fd+1;i<=maxfd;i++){//client_fd事件
            if(FD_ISSET(i,&rset)){
                char buffer[1024]={0};
                int count=recv(i,buffer,1024,0);
                if(count==0) {//disconnect
                    printf("client disconnect:%d\n",i);
                    FD_CLR(i,&rfds);//将client_fd移除监听集合
           
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值