12-27 I/O复用select
int select(int nfds,fd_set*readfds,fd_set* writefds,fd_set*exceptfds,struct timeval*timeout);
nfds是文件描述符的总数 ,写事件,读事件,异常事件,超时时间
有一个集合有1024个位,开始都是0,每一个位代表一个描述符,1代表这个描述符是有的文件,每一次都会扫描所有的1024个位,看有几个描述符,然后判断那几个描述符上有请求。
FD_ZERO(fd_set*fdset) ;//清除所有位
FD_SET(int fd,fd_set*fdset);//设置某一个位
FD_CLR(int fd,fd_set *fdset);//清除某一个位
int FD_ISSET(int fd,fd_set *fdset);//测试fdset的位是否有被设置
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/selectt.h>
#define STDIN 0//标准输入的描述符是0 ,键盘
int main()
{
int fd=STDIN;
fd_set fdset;
while(1)
{
FD_ZERO(&fdset);
FD_SET(fd,&fdset);
struct timeval tv={5,0};
int n=select(fd+1,&fdset,NULL,NULL,&tv);
if(n==-1)
{
printf("select err\n");
}
else if(n==0)
{
printf("time out\n");
}
else
{
if(FD_ISSET(fd,&fdset))
{
char buff[128]={0};
read(fd,buff,128);
printf("read:%s\n",buff);
}
}
}
}
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/selectt.h>
int socket_init();
void fds_init(int fds[])
{
int i=0;
for(;i<MAX;i++)
{
fds[i]=-1;
}
}
void fds_add(int fd,int fds[])
{
if(fd<0)
{
return ;
}
for(int i=0;i<MAX;i++)
{
if(fds[i]==-1)
{
fds[i]=fd;
break;
}
}
}
void fds_del(int fd,int fds[])
{
for(int i=0;i<MAX;i++)
{
if(fds[i]==fd)
{
fds[i]=-1;
break;
}
}
}
int main()
{
int sockfd=socket_init();
assert(sockfd!=-1);
int fds[MAX];//收集描述符
fds_init(fds);//清空
fds_add(sockfd,fds);
fd_set fdset;
while(1)
{
FD_ZERO(&fdset);
int maxfd=-1;
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<0)
{
printf("select err\n");
}
else if(n==0)
{
printf("time out\n");
}
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=accpet(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)
{
printf("client close\n");
close(fds[i]);
fds_del(fds[i],fds)
}
else
{
printf("recv(%d)=%s\n",fds[i],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;
memset(saddr,0,sizeof(saddr));
saddr.sin_family=AF_INET;
saddr.sin_port=htons(6000);
saddr.sin_saddr.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;
}