网络IO和事件循环的理解
一:
下面是用epoll实现一个服务端的伪代码:
int main()
{
int lfd=socket();
int epfd=epoll_create(3000); //epoll树根节点,3000只是个值,后面还会自动扩容
struct epoll_event all[3000]; //存储发送变化的fd对应信息
//init
//监听的lfd挂到epoll树上
struct epolll_event ev;
//在ev中初始化lfd信息
ev.events=EPOLLIN;
ev.data.fd=lfd;
epoll_ctl(epfd,EPOLL_CTL_ADD,lfd,&ev);
while(1)
{
int ret=epoll_wait(epfd,all,3000,-1); //ret表示多少个文件描述符发ret生了变化
//根据ret遍历all数组
for(int i=0;i<ret;i++)
{
int fd=all[i].data.fd;
//有新的连接
if(fd==lfd)
{
//接收连接请求
int cfd=accept();
//cfd上树
struct epoll_event temp;
temp.data.fd=cfd;
temp.events=EPOLLIN;
epoll_ctl(epfd,EPOLL_CTL_ADD,cfd,&temp);
}
else
{
//已经连接的客户端有数据发送过来
//只处理客户端发来的数据
if(!all[i].events&EPOLLIN)
{
continue;
}
char buf[50]={0};
int len=recv(fd,buf,sizeof(buf),0); //读数据
if(len==0)
{
close(fd);
//检测的fd从树上删除
epoll_ctl(epfd,EPOLL_CTL_DEL,fd,NULL); //删除结点,传个NULL
}
else
{
//发数据
write(STDOUT_FILENO,buf,len);
write(fd,buf,len);
}
}
}
}
return 0;
}
如下图所示,每个新的客户端发来的连接请求,相当上面的代码段中的 " int cfd=accept() ",而服务器就通过epoll来管理这些客户端。

二:
(1)啥是网络IO?
可以理解为socket,也可以说是fd,这个fd是新的连接请求产生的,类似上述代码的 int cfd=accept();其实就是socket,端对端的数据传输接口。再说得直观点,就是客户端连接服务器,服务器这边产生个fd,这个fd也就是所说的网络IO。
而服务器要管理成千上万的IO的时候,可以通过(select,poll,epoll)来管理。那么服务器如何知道客户端有数据过来的呢,就是通过(select,poll,epoll)来管理。
(2)事件循环
事件循环,相当于上述代码中的while(1)循环,循环里面监测struct epoll_event all[3000]这个数组中的哪个IO(fd),有数据可读,或者可写。
(3)那么事件的循环和epoll(select,poll)有啥关系的呢?
epoll(select ,poll)是实现事件循环的一个技术!!

浙公网安备 33010602011771号