epoll实现echo server和client
来源:互联网 发布:淘宝千人千面是什么 编辑:程序博客网 时间:2024/05/21 22:28
作为后端研发人员,竟然没搞清楚C/S模式,惭愧。。不爽。。
部分代码参考 http://blog.csdn.net/shanshanpt/article/details/7383400 感谢~~
- server.cpp
#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <errno.h>#include <sys/socket.h> // for socket#include <netinet/in.h> // for sockaddr_in#include <sys/epoll.h> // for epoll#include <fcntl.h> // for nonblocking#include <sys/resource.h> // for 最大连接数需要setrlimit#define MAXEPOLL 10000 // 对服务器来说,这个值可以很大#define MAXLINE 1024#define PORT 6000#define MAXBACK 1000int setnonblocking(int fd) { if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFD,0) | O_NONBLOCK) == -1) { printf("set blocking error: %d\n", errno); return -1; } return 0;}int main() { int listen_fd; int conn_fd; int epoll_fd; int nread; int cur_fds; // 当前已经存在的fd数量 int wait_fds; // epoll_wait的返回值 int i; struct sockaddr_in servaddr; struct sockaddr_in cliaddr; struct epoll_event ev; struct epoll_event evs[MAXEPOLL]; struct rlimit rlt; // 设置连接数所需 char buf[MAXLINE]; socklen_t len = sizeof(struct sockaddr_in); // 1.设置每个进程允许打开的最大文件数 rlt.rlim_max = rlt.rlim_cur = MAXEPOLL; if(setrlimit(RLIMIT_NOFILE, &rlt) == -1) { printf("setrlimit error : %d\n", errno); exit(EXIT_FAILURE); } // 2. 设置server地址 bzero(&servaddr, sizeof(servaddr)); // sa_family是地址家族,一般都是“AF_xxx”的形式。通常大多用的是都是AF_INET,代表TCP/IP协议族 servaddr.sin_family = AF_INET; // INADDR_ANY就是指定地址为0.0.0.0的地址,也就是表示本机的所有IP servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 必须要采用网络数据格式,普通数字可以用htons()函数转换成网络数据格式的数字 servaddr.sin_port = htons(PORT); // 3. 建立套接字 if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("socket error : %d ...\n", errno); exit(EXIT_FAILURE); } // 4. 设置非阻塞模式 if (setnonblocking(listen_fd) == -1) { printf("set non blocking error : %d ...\n", errno); exit(EXIT_FAILURE); } // 5. 绑定 if (bind(listen_fd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr)) == -1) { printf("bind error : %d ...\n", errno); exit(EXIT_FAILURE); } // 6. 监听 if (listen(listen_fd, MAXBACK) == -1) { printf("listen error : %d ...\n", errno); exit(EXIT_FAILURE); } // 7. 创建epoll epoll_fd = epoll_create(MAXEPOLL); ev.events = EPOLLIN | EPOLLET; // accept read ev.data.fd = listen_fd; // add listen_fd if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev) < 0) { printf("epoll_ctl error : %d\n", errno); exit(EXIT_FAILURE); } cur_fds = 1; while (true) { if ((wait_fds = epoll_wait(epoll_fd, evs, cur_fds, -1)) == -1) { printf("epoll_wait error : %d\n", errno); exit(EXIT_FAILURE); } for (i = 0; i < wait_fds; ++i) { if (evs[i].data.fd == listen_fd && cur_fds < MAXEPOLL) { if ((conn_fd = accept(listen_fd, (struct sockaddr *)&cliaddr, &len)) == -1) { printf("accept error : %d\n", errno); exit(EXIT_FAILURE); } printf("server get from client port : %d\n", cliaddr.sin_port); ev.events = EPOLLIN | EPOLLET; ev.data.fd = conn_fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, conn_fd, &ev) < 0) { printf("epoll error : %d\n", errno); exit(EXIT_FAILURE); } ++cur_fds; continue; } // 处理数据 nread = read(evs[i].data.fd, buf, sizeof(buf)); if (nread < 0) { close(evs[i].data.fd); epoll_ctl(epoll_fd, EPOLL_CTL_DEL, evs[i].data.fd, &ev); --cur_fds; continue; } buf[nread] = 'a'; buf[nread + 1] = '\0'; // 回写 write(evs[i].data.fd, buf, nread); } } close(listen_fd); return 0;}
- client.cpp
#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <netinet/in.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <sys/select.h>#include <sys/epoll.h> // for epoll#include <fcntl.h>#define MAXEPOLL 10000#define MAXLINE 1024#define SERV_PORT 6000int setnonblocking(int fd) { if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFD,0) | O_NONBLOCK) == -1) { printf("set blocking error: %d\n", errno); return -1; } return 0;}void send_and_recv_epoll(int conn_fd) { int epoll_fd; int cur_fds; int wait_fds; struct epoll_event ev; struct epoll_event evs[MAXEPOLL]; char send[MAXLINE]; char recv[MAXLINE]; int lens; int n; int i = 0; FILE* fp = stdin; epoll_fd = epoll_create(MAXEPOLL); ev.events = EPOLLIN | EPOLLOUT | EPOLLET; ev.data.fd = conn_fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, conn_fd, &ev) < 0) { printf("epoll_ctl error : %d\n", errno); exit(EXIT_FAILURE); } ++cur_fds; // 即cur_fds = 1; while (true) { if ((wait_fds = epoll_wait(epoll_fd, evs, cur_fds, -1)) == -1) { printf("epoll_wait error : %d\n", errno); exit(EXIT_FAILURE); } for (i = 0; i < wait_fds; ++i) { if (evs[i].events & EPOLLIN) { printf("EPOLLIN ...\n"); printf("client get from server ...\n"); memset(recv, 0, sizeof(recv)); n = read(evs[i].data.fd, recv, MAXLINE); // read错误判断 if (n == 0) { printf("recv OK ...\n"); continue; } else if (n == -1) { printf("recv ERROR ...\n"); continue; } else { lens = strlen(recv); recv[lens] = '\0'; printf("write to stdout...\n"); write(STDOUT_FILENO, recv, MAXLINE); printf("\n"); } } if (evs[i].events & EPOLLOUT) { printf("EPOLLOUT ...\n"); memset(send, 0, sizeof(send)); if (fgets(send, MAXLINE, fp) == NULL) { printf("End ...\n"); exit(EXIT_FAILURE); } else { lens = strlen(send); send[lens - 1] = '\0'; if (strcmp(send, "q") == 0) { printf("Bye ...\n"); return; } printf("client send: %s\n", send); write(evs[i].data.fd, send, strlen(send)); // 错误判断 } } } }}void send_and_recv(int conn_fd) { FILE* fp = stdin; int lens; char send[MAXLINE]; char recv[MAXLINE]; fd_set rset; // select()机制中提供一fd_set的数据结构 FD_ZERO(&rset); int maxfd = (fileno(fp) > conn_fd ? fileno(fp) : (conn_fd + 1)); int n; while (true) { FD_SET(fileno(fp), &rset); FD_SET(conn_fd, &rset); if (select(maxfd, &rset, NULL, NULL, NULL) == -1) { printf("client select error ...\n"); exit(EXIT_FAILURE); } if (FD_ISSET(conn_fd, &rset)) { printf("client get from server ...\n"); memset(recv, 0, sizeof(recv)); n = read(conn_fd, recv, MAXLINE); if (n == 0) { printf("recv OK ...\n"); break; } else if (n == -1) { printf("recv ERROR ...\n"); break; } else { lens = strlen(recv); recv[lens] = '\0'; write(STDOUT_FILENO, recv, MAXLINE); printf("\n"); } } if (FD_ISSET(fileno(fp), &rset)) { memset(send, 0, sizeof(send)); if (fgets(send, MAXLINE, fp) == NULL) { printf("End ...\n"); exit(EXIT_FAILURE); } else { lens = strlen(send); send[lens - 1] = '\0'; if (strcmp(send, "q") == 0) { printf("Bye ...\n"); return; } printf("client send: %s\n", send); write(conn_fd, send, strlen(send)); } } }}int main(int argc, char** argv) { int conn_fd; struct sockaddr_in servaddr; if (argc != 2) { printf("input server ip! \n"); exit(EXIT_FAILURE); } if ((conn_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("socket error...\n"); exit(EXIT_FAILURE); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERV_PORT); inet_pton(AF_INET, argv[1], &servaddr.sin_addr); if (connect(conn_fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) { printf("connect error...\n"); exit(EXIT_FAILURE); } if (setnonblocking(conn_fd) == -1) { printf("set non blocking error : %d ...\n", errno); exit(EXIT_FAILURE); } send_and_recv_epoll(conn_fd); //send_and_recv(conn_fd); close(conn_fd); printf("Exit\n"); return 0;}
阅读全文
0 0
- 采用epoll实现echo server和client
- epoll实现echo server和client
- java 多线程Echo server和client 例子
- java socket通讯之 echo server 和echo client例子
- 回射客户端服务器epoll( echo client && server improved by epoll function )
- ECHO TCP Server Client
- epoll - socket-server-client
- epoll server client
- twisted-01 Echo server and echo client
- UDP Client Server Echo Example
- epoll实现简单echo服务器
- epoll例程——简单的server和client
- NIO 实现server和client
- libevent for echo server and client
- libevent for echo server and client
- CMU440-P0:Implementing a multi-client echo server(实现一个多客户端回显服务器)
- 用epoll实现异步的Echo服务器
- WCF基本实现(Server和Client)
- C++中sizeof和strlen
- 线程池ThreadPool与Application.DoEvents()
- 如何使用数组参数
- 在STM8L上实现IAP(In Application Programming)
- 把uuid加入DataFrame中并存入SQLite3数据库
- epoll实现echo server和client
- 未将对象引用设置到对象的实例 问题原因总结
- Hibernate Validator注解大全
- JSP的9大内置对象和4个作用域
- text/html & text/plain的区别
- Ecmall 模型分析
- Anroid 开发小技巧 | linux下懒人快捷Terminal命令
- Android音视频API(android.media.tv):概览
- Mac上adb: command not found问题解决办法