Linux:select

10_10
I/O复用方法:select poll epoll
文件描述符:select > 0
fd_set,fd_isset,检测多个描述符,程序处理多个文件描述符

Http服务器端代码:

```c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.t>
#include<arpa/inet.h>
#include<assert.h>
#include<fcntl.h>
#include<sys/select.h>
#include<syys/time.h>

#define MAX 10

int socket_init();
void fds_init(int fds[])
{
    
    
    if(fds==NULL)
    {
    
    
        return;
    }
    for(int i=0;i<MAX;i++)
    {
    
    
        fds[i]=-1;
    }
}
void fds_add(int fd,int fds())//添加描述符
{
    
    
    if(fds==NULL)
    {
    
    
        return;
	}
    
    for(int i=0;i<MAX;i++)
    {
    
    
        if(fds[i]==-1)
        {
    
    
            fds[i]=fd;
            break;
        }
    }
}
void fds_del(int fd,int fds[])//移除数组指定描述符
{
    
    
    if(fds==NULL)
    {
    
    
        return ;
	}
    
    for(int i=0;i<MAX;i++)
    {
    
    
        if(fds[i]==fd)
        {
    
    
            fds[i]=-1;
            break;
		}
	}
}
int main()
{
    
    
    int socket=socket_init;
    assert(sockfd!=-1);
    
    int fds[MAX];
    fds_init(fds);//初始化数组值为-1,代表数组为空
    fds_add(sockfd,fds);//将监听套接字添加到数组中
    
    fd_set fdset;//集合 ->select
    
    while(1)
    {
    
    
        FD_ZERO(&fdset);//清空集合
        int maxfd=-1;//记录描述符最大值,最大值传给select
        
        for(int i=0;i<MAX;i++)//将数组有效值传入
        {
    
    
            if(fds[i]==-1)
            {
    
    
                continue;
			}
            
            FD_SET(fds[i]&fdset)//把有效描述符添加到集合,并且找到最大值添加
            if(maxfd<fds[i])
            {
    
    
                maxfd=fds[i];
			}
        }
        
        struct timeval tv={
    
    5,0};
        int n=select(maxfd+1,&fdset,NULL,NULL,&tv);//有可能会发生阻塞,如果超时的话
        if(n==-1)
        {
    
    
            continue;
        }
        else if(n==0)
        {
    
    
            printf("time out\n");
            continue;
		}
        else
        {
    
    
            for(int i=0;i<MAX;i++)//遍历所有描述符,找到就绪的,找到所有有数据的
            {
    
    
                if(fds[i]==-1)//清除空位
                {
    
    
                    continue;
                }
                if(FD_ISSET(fds[i],&fdset))
                {
    
    
                    if(fds[i]==sockfd)
                    {
    
    
                        struct sockaddr_in caddr;
                        int len=sizeof(caddr);
                        
                        int c=accept(sockfd,(struct sockaddr*)&caddr,&len);
                        if(c<0)
                        {
    
    
                            continue;
                        }
                        
                        printf("accept c = %d\n",c);
                        fds_add(c,fds);
					}
                    else
                    {
    
    
                        char buff[128]={
    
    0};
                        int num=recv(fds[i],buff,127,0);
                        if(num<=0)
                        {
    
    
                            close(fds[i]);
                            fds_del(fds[i],fds);//从数组删除不用的描述符
                            printf("client close\n");
                            continue;
                        }
                        
                        printf("read:%s\n",buff);
                        send(fds[i],"ok",2,0);
                    }
				}
            }
        }
    }
}
int socket_init()
{
    
    
    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd==-1)
    {
    
    
        return -1;
	}
    
    struct sockaddr_in saddr;
    mem(&saddr,0,sizeof(saddr));
    saddr.sin_family=AF_INET;
    saddr.sin_port=htons(80);
    saddr.sin_addr.s_addr=inet_addr("127.0.0.1");
    
    int res=bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if(res==-1)
    {
    
    
        return -1;
    }
    
    res=listen(sockfd,5);
    if(res==-1)
    {
    
    
        return -1;
    }
    return sockfd;
}

1.对方关闭描述符

2.对方发数据

3.对方链接

select都会返回


猜你喜欢

转载自blog.csdn.net/qq_48580892/article/details/120687520
今日推荐