38、epoll
【摘要】 epoll
epoll - I / O事件通知工具 所述epoll的 API执行类似的任务轮询(2) :监控多个 文件描述符来查看是否有任何I / O是可能的。该epoll的 API可以用作边缘触发或电平触发界面和扩展到大量的观看文件 描述。提供以下系统调用来创建和管理一个epoll实。
创建一个套接字,绑定,检测服务器 1. 创建套接字 2. 填充本地 s...
epoll
epoll - I / O事件通知工具
所述epoll的 API执行类似的任务轮询(2) :监控多个 文件描述符来查看是否有任何I / O是可能的。该epoll的 API可以用作边缘触发或电平触发界面和扩展到大量的观看文件
描述。提供以下系统调用来创建和管理一个epoll实。
创建一个套接字,绑定,检测服务器
1. 创建套接字
2. 填充本地 sockaddr_in 结构体(设置本地的IP地址和端口)
3. bind()绑定
4. listen()监听检测服务器
main:
首先创建一个绑定了本地ip和端口号的套接字描述符
- 创建epoll
- epoll结构 填充(初始化关心事件为读)
- 托管(将listen sock添加到epfd中,关心读事件)
- 检测事件
- epoll_wait返回大于零,即就是返回了需要处理事件的数目
startup
int startup(char* _ip,int _port) //创建一个套接字,绑定,检测服务器
{
---------------------------------------
//1.创建套接字
int sock=socket(AF_INET,SOCK_STREAM,0); if(sock<0){ perror("sock"); exit(2);
} int opt = 1; //*setsockopt()函数用于任意类型、任意状态套接口的设置选项值。*/
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
---------------------------------------
//2.填充本地 sockaddr_in 结构体(设置本地的IP地址和端口)
struct sockaddr_in local; local.sin_port=htons(_port);
local.sin_family=AF_INET;
local.sin_addr.s_addr=inet_addr(_ip);
---------------------------------------
//3.bind()绑定
if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0) { perror("bind"); exit(3);
}
---------------------------------------
//4.listen()监听 检测服务器
if(listen(sock,5)<0){ perror("listen"); exit(4);
}
return sock; //这样的套接字返回
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
int main(int argc,char *argv[])
{
----------------------检测参数个数是否正确--------------------------
if(argc!=3){ usage(argv[0]); exit(1); }
}
-----------------------------------------------------------------
int listen_sock=startup(argv[1],atoi(argv[2])); //创建一个绑定了本地 ip 和端口号的套接字描述符
-----------------------------创建epoll-------------------------------
int epfd = epoll_create(256); //可处理的最大句柄数256个 if(epfd < 0){ perror("epoll_create"); exit(5); } struct epoll_event _ev; //epoll结构填充 _ev.events = EPOLLIN; //初始关心事件为读 _ev.data.fd = listen_sock; ------------------------------托管--------------------------------- epoll_ctl(epfd,EPOLL_CTL_ADD,listen_sock,&_ev); //将listen sock添加到epfd中,关心读事件 struct epoll_event revs[64]; int timeout = -1; int num = 0; int done = 0;
------------------------------j检测事件-------------------------------- while(!done){ switch((num = epoll_wait(epfd,revs,64,timeout))) //返回需要处理的事件数目 64表示 事件有多大 { case 0: //返回0 ,表示监听超时 printf("timeout\n"); break; case -1: //出错 perror("epoll_wait"); break; default: //大于零 即就是返回了需要处理事件的数目 { struct sockaddr_in peer; socklen_t len = sizeof(peer); int i; for(i=0;i < num;i++){ int rsock = revs[i].data.fd; //准确获取哪个事件的描述符 ---------------------------------------------- if(rsock == listen_sock && (revs[i].events) && EPOLLIN){ //如果是初始的就接受,建立链接 int new_fd = accept(listen_sock,(struct sockaddr*)&peer,&len); if(new_fd > 0){ printf("get a new client:%s:%d\n",inet_ntoa(peer.sin_addr),ntohs(peer.sin_port)); set_nonblock(new_fd); _ev.events = EPOLLIN | EPOLLET; _ev.data.fd = new_fd; //二次托管 epoll_ctl(epfd,EPOLL_CTL_ADD,new_fd,&_ev); } }else{ //对num-1个事件处理 }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
文章来源: xuesong.blog.csdn.net,作者:内核笔记,版权归原作者所有,如需转载,请联系作者。
原文链接:xuesong.blog.csdn.net/article/details/79210652
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)