epoll实例
2014-07-01 09:17
86 查看
#include <iostream> #include <sys/socket.h> #include <sys/epoll.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <stdio.h> #define SERV_PORT 8888 //端口号 #define MAX_LEN 100 //最大连接数 #define LISTENQ 20 //等待数 using namespace std; //设置socket为非阻塞模式 int setnoblocking(int sockfd) {/*{{{*/ if(fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) { return 1; } /*int opts; //获取打开方式 opts = fcntl(sockfd, F_GETFD, 0); if(opts < 0) { cout << "opts F_GETFL error!!" << endl; return 1; } opts = opts | O_NONBLOCK; //设置文件描述符 if(fcntl(sockfd, F_SETFL, opts) < 0) { cout << "opts F_SETFL error!!" << endl; return 1; }*/ return 0; }/*}}}*/ //操作消息 int handle_message(int connfd) { //缓冲变量 char buf[1024]; //获取的长度 int len = 0; len = recv(connfd, buf, 1024, 0); if(len < 0) { cout << "数据接收失败" << endl; close(connfd); return -1; } printf("%d消息接收成功%s,maxlen%d", connfd, buf, len); return len; } //主函数 int main ( int argc, char *argv[] ) {/*{{{*/ int listfd, epfd, nfds, i, connfd, curfds, ret; //客户端长度 socklen_t client_len; client_len = sizeof(struct sockaddr_in); //客户端socket地址 struct sockaddr_in clientaddr; //服务端socket地址 struct sockaddr_in serveraddr; //epoll ev 事件注册,events事件回调 struct epoll_event ev, events[20]; //创建epoll文件符 epfd = epoll_create(256); //创建socket文件符 listfd = socket(AF_INET, SOCK_STREAM, 0); //将socket设置为非阻塞模式 if(setnoblocking(listfd) > 0) { cout << "socket noblocking error!!"; return 0; } //设置epoll要处理的相关文件符 ev.data.fd = listfd; //epoll要处理的事件类型 ev.events = EPOLLIN | EPOLLET; //注册epoll事件 epoll_ctl(epfd, EPOLL_CTL_ADD, listfd, &ev); //将服务端地址清空 bzero(&serveraddr, sizeof(serveraddr)); //设置服务端信息 serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(SERV_PORT); serveraddr.sin_ 4000 addr.s_addr = INADDR_ANY; //设置IP地址 //char *local_addr = "127.0.0.1"; //inet_aton(local_addr, &(serveraddr.sin_addr)); if(bind(listfd, (sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) { cout << "bind listfd error!!" << endl; return 0; } //等待数 if(listen(listfd, LISTENQ) < 0) { cout << "list error!!" << endl; return 0; } //当前文件符 curfds = 1; while(1) { //等待事件发生 nfds = epoll_wait(epfd, events, curfds, -1); //处理所有发生的事件 for(i = 0; i < nfds; i++) { if(events[i].data.fd == listfd) { //获取连接符 connfd = accept(listfd, (struct sockaddr *)&clientaddr, &client_len); if(connfd < 0) { cout << "connfd error!!" << endl; continue; } //设置连接文件符为非阻塞模式 setnoblocking(connfd); //将epoll设置到连接符上 ev.events = EPOLLIN | EPOLLET; ev.data.fd = connfd; if(epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev) < 0) { return -1; } curfds++; } else { //获取请求信息 ret = handle_message(events[i].data.fd); if(ret < 1) { //删除fd epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, &ev); curfds--; } } } } close(listfd); return 0; }/*}}}*/
相关文章推荐
- epoll使用实例说明
- epoll详解(三)-- ET模式实例
- epoll完整实例
- 彻底学会使用epoll(四)——ET的写操作实例分析
- epoll_create, epoll_ctl和epoll_wait 实例讲解,总结得不错
- 如何使用 epoll? 一个 C 语言实例
- epoll使用实例说明
- linux epoll TCP UDP 实例
- epoll测试实例
- Linux Epoll程序实例
- Linux Epoll介绍和程序实例
- [原]高级I/O复用技术:Epoll的使用及一个完整的C实例
- Linux Epoll介绍和程序实例
- 如何使用 epoll? 一个 C 语言实例
- epoll 使用实例
- 实例浅析epoll的水平触发和边缘触发,以及边缘触发为什么要使用非阻塞IO
- epoll_create, epoll_ctl和epoll_wait 实例讲解
- epoll使用实例
- epoll实例
- epoll网络编程实例