Linux网络编程——epoll服务器编写
来源:互联网 发布:福州seo推广 编辑:程序博客网 时间:2024/06/14 01:43
epoll服务器端代码:
#include<stdio.h>#include<sys/epoll.h>#include<sys/socket.h>#include<sys/type.h>#include<netinet/in.h>#include<arpa/inet.h>#include<stdlib.h>#include<string.h>static void usage(const char *proc){ printf("Usage: %s [local_ip] [local_port]\n",proc);}typedef struct fd_buf{ int fd; char buf[10240];}fd_buf_t,*fd_buf_p;static void *alloc_fd_buf(int fd){ fd_buf_p tmp = (fd_buf_p)malloc(sizeof(fd_buf_t)); if(!tmp){ perror("malloc"); return NULL; } tmp->fd = fd; return tmp;}int startup(const char *_ip, int _port){ int sock = socket(AF_INET,SOCK_STREAM,0); if(sock < 0){ perror("socket"); exit(2); } int opt = 1; setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); struct sockaddr_in local; local.sin_family = AF_INET; local.sin_port = htos(_port); local.sin_addr.s_addr = inet_addr(_ip); if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0){ perror("bind"); exit(3); } if(listen(sock, 10) < 0){ perror("listen"); exit(4); } return sock;}int main(int argc,char *argv[]){ if(argc != 3){ usage(argv[0]); return 1; } int listen_sock = startup(argv[1], atoi(argv[2])); int epollfd = epoll_create(256); if(epollfd < 0){ perror("epoll_create"); close(listen_sock); return 5; } struct epoll_event ev; ev.events = EPOLLIN; ev.data.ptr = alloc_fd_buf(listen_sock); epoll_ctl(epollfd,EPOLL_CTL_ADD,listen_sock,&ev); int nums = 0; struct epoll_event_evs[64]; int timeout = -1; while(1){ switch((nums = epoll_wait(epollfd,evs,64,timeout))){ case -1: perror("epoll wait"); break; case 0: printf("timeout...!\n"); break; default: { int i = 0; for(; i<nums ;i++){ fd_buf_p fp = (fd_buf_p)evs[i].data.ptr; if(fp->fd == listen_sock &&\ (evs[i].events & EPOLLIN)){ struct sockaddr_in client; socklen_t len = sizeof(client); int new_sock = accept(listen_sock,\ (struct sockaddr*)&client,&len); if(new_sock < 0){ perror("accept"); continue; } printf("get a new client\n"); ev.events = EPOLLIN; ev.data.ptr = alloc_fd_buf(new_sock); epoll_ctl(epollfd, EPOLL_CTL_ADD,\ new_sock,&ev); } else if(fp->fd != listen_sock){ if(evs[i].events & EPOLLIN){ ssize_t s = read(fp->fd, fp->buf,\ sizeof(fp->buf)); if(s > 0){ fp->buf[s] = 0; printf("client say: %s\n",fp->buf); ev.events = EPOLLOUT; ev.data.ptr = fp; epoll_ctl(epollfd,EPOLL_CTL_MOD,\ fp->fd,&ev); }else if(s<=0){ close(fp->fd); epoll_ctl(epollfd, EPOLL_CTL_DEL,\ fp->fd,NULL); free(fp); }else{ } }else if(evs[i].events & EPOLLOUT){ const char *msg = "HTTP/1.0 200 OK\r\n\r\n<html><h1>hello epoll!</h1></html>"; write(fp->fd, msg ,strlen(msg)); close(fp->fd); epoll_ctl(epollfd,EPOLL_CTL_DEL,\ fp->fd,NULL); free(fp); }else{ } }else{ } }//for } break; } } return 0;}
epoll优点:
1. 支持一个进程打开大数目的socket描述符。
2. IO效率不随fd数目增加而线性下降,传统的select/poll每次调用都会线性扫描全部的集合,导致效率呈现线性下降。
3. 使用mmap加速内核与用户空间的消息传递。无论是select,poll还是epoll都需要内核把fd消息通知给用户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。
阅读全文
0 0
- Linux网络编程——epoll服务器编写
- Linux网络编程之epoll服务器
- Linux网络编程——tcp并发服务器(epoll实现)
- Linux网络编程——tcp并发服务器(epoll实现)
- Linux【网络编程】——I/O多路转接之epoll服务器
- Linux网络编程——tcp并发服务器(epoll实现)
- linux服务器编程--EPOLL
- linux 网络编程 epoll
- linux网络编程——多路复用epoll模型简例
- Linux C 网络编程——7.select poll epoll
- Linux网络编程——epoll学习笔记
- 嵌入式 Linux网络编程(五)——epoll机制
- linux c/c++网络编程之—epoll 模型
- Linux网络编程epoll模型
- Linux网络编程epoll模型
- linux网络编程之 epoll
- linux网络编程之 epoll
- Linux网络编程之epoll
- 【Kotlin】一个有趣的商品数量加减交互控件(商详页或者购物车商品数量的加减)
- python2.7基于selenium的web自动化测试项目--框架设计
- 制作本地YUM源
- Android ping
- Socket通信——TCP、UDP区别总结、使用场景
- Linux网络编程——epoll服务器编写
- Jsp格式化显示Date类型数据
- Homebrew简介及安装
- Android探索之路:实现点击验证码图片更换功能
- 高性能服务器之select
- SpringBoot添加AOP处理请求
- nginx 启动,停止和重新加载配置
- Android7.0中文文档(API) -- AbsListView.RecyclerListener
- 全景图处理插件