epoll处理多连接
来源:互联网 发布:如何连接宽带网络 编辑:程序博客网 时间:2024/06/07 16:34
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netdb.h>#include <unistd.h>#include <fcntl.h>#include <sys/epoll.h>#include <errno.h>#include <libgen.h>#define MAXEVENTS 1024#define BUF_SIZE 100//set this descriptor non blockingstatic int set_non_block(int sfd){ int flags, s; flags = fcntl(sfd, F_GETFL, 0); if (flags == -1) { perror ("fcntl"); return -1; } flags |= O_NONBLOCK; s = fcntl(sfd, F_SETFL, flags); if (s == -1) { perror ("fcntl"); return -1; } return 0;}//static int create_and_bind (char *port){ struct addrinfo hints; struct addrinfo *result, *rp; int s, sfd; memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_UNSPEC; //IPv4 IPv6通用 hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */ hints.ai_flags = AI_PASSIVE; //监听套接字; //根据暗示得到所有可用的addrinfo s = getaddrinfo (NULL, port, &hints, &result); if (s != 0){ fprintf (stderr, "getaddrinfo: %s\n", gai_strerror (s)); return -1; } //use the first addr to create socket for (rp = result; rp != NULL; rp = rp->ai_next) { sfd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sfd == -1) continue; s = bind (sfd, rp->ai_addr, rp->ai_addrlen); if (s == 0) { //bind success break; } close (sfd);//if bind failed we close this socket } if (rp == NULL) { fprintf (stderr, "Could not bind\n"); return -1; } freeaddrinfo (result); return sfd;}// add EPOLLIN event of fd to the epollfd, and epoll uses EPOLLLT in defaultvoid addfd(int epollfd, int fd, int enable_et){ struct epoll_event event; event.data.fd = fd; event.events = EPOLLIN; if(enable_et) event.events |= EPOLLET; epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event); set_non_block(fd);}//the level-trigger logicvoid lt(struct epoll_event *events, int number, int epollfd, int listenfd){ char buf[BUF_SIZE]; int i; for(i = 0; i < number; i++){ int sockfd = events[i].data.fd; //new client connection if(sockfd == listenfd){ struct sockaddr_in client_addr; socklen_t client_addrlen = sizeof(client_addr); int connfd = accept(listenfd, (struct sockaddr *)&client_addr, &client_addrlen); if(connfd < 0){ perror("accept failed.."); exit(-1); } //register this event addfd(epollfd, connfd, 0); }else if(events[i].events & EPOLLIN){ //if there exists data unreaded , this code will invoke memset(buf, 0, sizeof(buf)); printf("sockefd %d read event trigger once\n", sockfd); int ret = recv(sockfd, buf, BUF_SIZE, 0); if(ret <= 0){ printf("some read error or client closed.\n"); close(sockfd); // will unregister continue; } printf("get %d bytes from client: %s\n", ret, buf); }else{ // what we are not interested printf("something else happened\n"); } }}//the edge-trigger logicvoid et(struct epoll_event *events, int number, int epollfd, int listenfd){ char buf[BUF_SIZE]; int i; for(i = 0; i < number; i++){ int sockfd = events[i].data.fd; //new client connection if(sockfd == listenfd){ struct sockaddr_in client_addr; socklen_t client_addrlen = sizeof(client_addr); int connfd = accept(listenfd, (struct sockaddr *)&client_addr, &client_addrlen); if(connfd < 0){ perror("accept failed.."); exit(-1); } //register this event and set edge trigger mode addfd(epollfd, connfd, 1); }else if(events[i].events & EPOLLIN){ //in this mode , we should read all the data out once printf("sockefd %d read event trigger once\n", sockfd); while(1){ memset(buf, 0, sizeof(buf)); int ret = recv(sockfd, buf, BUF_SIZE, 0); if(ret < 0){ //for the nonblocking IO,the following errors indicate the read complete if(errno == EAGAIN || errno == EWOULDBLOCK){ printf("read later\n"); break; } printf("some other error\n"); close(sockfd); // will unregister break; }else if(ret == 0){ printf("client closed.\n"); close(sockfd); break; }else{ printf("get %d bytes from client: %s\n", ret, buf); } } }else{ // what we are not interested printf("something else happened\n"); } }}int main (int argc, char *argv[]){ int sfd, s; int efd; struct epoll_event event; struct epoll_event events[MAXEVENTS]; if (argc < 2){ fprintf (stderr, "Usage: %s [port]\n", basename(argv[0])); exit (EXIT_FAILURE); } sfd = create_and_bind (argv[1]); if (sfd == -1) abort (); //listen for connection coming s = listen (sfd, SOMAXCONN); if (s == -1) { perror ("listen"); abort (); } //create a epoll object efd = epoll_create1 (0); if (efd == -1) { perror ("epoll_create"); abort (); } //add the listen socket to the event poll addfd(efd, sfd, 1); while(1){ int ret = epoll_wait(efd, events, MAXEVENTS, -1); if(ret < 0){ printf("epoll wait failture..\n"); break; } //et(events, ret, efd, sfd); lt(events, ret, efd, sfd); } close (sfd); return EXIT_SUCCESS;}调用的时候 root@root# ./epolltest 5000
0 0
- epoll处理多连接
- python 使用epoll异步处理多个客户端的连接
- epoll同时处理海量连接的代码
- epoll + 多线程实现并发网络连接处理
- epoll + 多线程实现并发网络连接处理
- epoll + 多线程实现并发网络连接处理
- epoll + 多线程实现并发网络连接处理
- epoll处理高并发连接丢失连接的问题
- epoll处理
- 一步一步学epoll同时处理海量连接的代码
- linux下的epoll如何高效处理百万连接
- 唯快不破:linux下的epoll如何高效处理百万连接
- Nginx事件处理(epoll)
- epoll处理并发
- epoll event 处理
- Linux网络编程一步一步学-epoll同时处理海量连接的代码
- Linux网络编程一步一步学-epoll同时处理海量连接的代码
- Linux网络编程一步一步学-epoll同时处理海量连接的代码
- HDU 2874 LCA离线算法 tarjan算法
- POJ 1905 Expanding Rods
- 计算两个日期间的天数
- chrome 一进入调试页面就会自动打断点
- 黑马程序员——JAVA基础------集合框架(二)----Set接口
- epoll处理多连接
- HTML5表单详细介绍
- MyEclipse或Eclipse安装PyDev插件
- PAT 《C/C++/Java/Pascal 程序设计基础》习题集 (1) IO
- 带有引用计数的智能指针
- 使用Vi/Vim给文件加密和解密
- java如何将一组对象传入Oracle存储过程
- 记一下关于Instantiate时Awake Start的执行
- 分布式系统的特点以及设计理念