epoll
来源:互联网 发布:文件制作软件 编辑:程序博客网 时间:2024/06/05 17:51
http://blog.csdn.net/jnu_simba/article/details/9075719
read_write.h
ssize_t readn(int fd, void *buf, size_t count) { size_t nleft = count; ssize_t nread; char *bufp = (char *)buf; while (nleft > 0) { if ((nread = read(fd, bufp, nleft)) < 0) { if (errno == EINTR) continue; return -1; } else if (nread == 0) //对方关闭或者已经读到eof return count - nleft; bufp += nread; nleft -= nread; } return count; } ssize_t writen(int fd, const void *buf, size_t count) { size_t nleft = count; ssize_t nwritten; char *bufp = (char *)buf; while (nleft > 0) { if ((nwritten = write(fd, bufp, nleft)) < 0) { if (errno == EINTR) continue; return -1; } else if (nwritten == 0) continue; bufp += nwritten; nleft -= nwritten; } return count; } /* recv()只能读写套接字,而不能是一般的文件描述符 */ ssize_t recv_peek(int sockfd, void *buf, size_t len) { while (1) { int ret = recv(sockfd, buf, len, MSG_PEEK); // 设置标志位后读取后不清除缓冲区 if (ret == -1 && errno == EINTR) continue; return ret; } } /* 读到'\n'就返回,加上'\n' 一行最多为maxline个字符 */ ssize_t readline(int sockfd, void *buf, size_t maxline) { int ret; int nread; char *bufp = (char*)buf; int nleft = maxline; int count = 0; while (1) { ret = recv_peek(sockfd, bufp, nleft); if (ret < 0) return ret; // 返回小于0表示失败 else if (ret == 0) return ret; //返回0表示对方关闭连接了 nread = ret; int i; for (i = 0; i < nread; i++) { if (bufp[i] == '\n') { ret = readn(sockfd, bufp, i + 1); if (ret != i + 1) exit(EXIT_FAILURE); return ret + count; } } if (nread > nleft) exit(EXIT_FAILURE); nleft -= nread; ret = readn(sockfd, bufp, nread); if (ret != nread) exit(EXIT_FAILURE); bufp += nread; count += nread; } return -1; }
#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <signal.h>#include <fcntl.h>#include <sys/wait.h>#include <sys/epoll.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <vector>#include <algorithm>#include "read_write.h"//#include <sysutil.h>#define ERR_EXIT(m) \ do { \ perror(m); \ exit(EXIT_FAILURE); \ } while (0) void activate_nonblock(int fd){int ret;int flags = fcntl(fd, F_GETFL);if (flags == -1)ERR_EXIT("fcntl");flags |= O_NONBLOCK;ret = fcntl(fd, F_SETFL, flags);if (ret == -1)ERR_EXIT("fcntl");}void deactivate_nonblock(int fd){int ret;int flags = fcntl(fd, F_GETFL);if (flags == -1)ERR_EXIT("fcntl");flags &= ~O_NONBLOCK;ret = fcntl(fd, F_SETFL, flags);if (ret == -1)ERR_EXIT("fcntl");}typedef std::vector<struct epoll_event> EventList;/* 相比于select与poll,epoll最大的好处是不会随着关心的fd数目的增多而降低效率 */int main(void){int count = 0;int listenfd;if ((listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)ERR_EXIT("socket");struct sockaddr_in servaddr;memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(1234);servaddr.sin_addr.s_addr = htonl(INADDR_ANY);int on = 1;if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)ERR_EXIT("setsockopt");if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)ERR_EXIT("bind");if (listen(listenfd, SOMAXCONN) < 0)ERR_EXIT("listen");std::vector<int> clients;int epollfd;epollfd = epoll_create1(EPOLL_CLOEXEC); //epoll实例句柄struct epoll_event event;event.data.fd = listenfd;event.events = EPOLLIN | EPOLLET; //边沿触发epoll_ctl(epollfd, EPOLL_CTL_ADD, listenfd, &event);EventList events(16);struct sockaddr_in peeraddr;socklen_t peerlen;int conn;int i;int nready;while (1){nready = epoll_wait(epollfd, & *events.begin(), static_cast<int>(events.size()), -1);if (nready == -1){if (errno == EINTR)continue;ERR_EXIT("epoll_wait");}if (nready == 0)continue;if ((size_t)nready == events.size())events.resize(events.size() * 2);for (i = 0; i < nready; i++){if (events[i].data.fd == listenfd){peerlen = sizeof(peeraddr);conn = accept(listenfd, (struct sockaddr *)&peeraddr, &peerlen);if (conn == -1)ERR_EXIT("accept");printf("ip=%s port=%d\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port));printf("count = %d\n", ++count);clients.push_back(conn);activate_nonblock(conn);event.data.fd = conn;event.events = EPOLLIN | EPOLLET;epoll_ctl(epollfd, EPOLL_CTL_ADD, conn, &event);}else if (events[i].events & EPOLLIN){conn = events[i].data.fd;if (conn < 0)continue;char recvbuf[1024] = {0};int ret = readline(conn, recvbuf, 1024);if (ret == -1)ERR_EXIT("readline");if (ret == 0){printf("client close\n");close(conn);event = events[i];epoll_ctl(epollfd, EPOLL_CTL_DEL, conn, &event);clients.erase(std::remove(clients.begin(), clients.end(), conn), clients.end());}fputs(recvbuf, stdout);writen(conn, recvbuf, strlen(recvbuf));}}}return 0;}
#include<stdio.h>#include<sys/types.h>#include<sys/socket.h>#include<unistd.h>#include<stdlib.h>#include<errno.h>#include<arpa/inet.h>#include<netinet/in.h>#include<string.h>#define ERR_EXIT(m) \ do { \ perror(m); \ exit(EXIT_FAILURE); \ } while (0)int main(void){int sock;if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) // listenfd = socket(AF_INET, SOCK_STREAM, 0)ERR_EXIT("socket error");struct sockaddr_in servaddr;memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(1234);servaddr.sin_addr.s_addr = inet_addr("192.168.1.253");/* inet_aton("127.0.0.1", &servaddr.sin_addr); */if (connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)ERR_EXIT("connect error");char sendbuf[1024] = {0};char recvbuf[1024] = {0};while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL){write(sock, sendbuf, strlen(sendbuf));read(sock, recvbuf, sizeof(recvbuf));fputs(recvbuf, stdout);memset(sendbuf, 0, sizeof(sendbuf));memset(recvbuf, 0, sizeof(recvbuf));}close(sock);return 0;}
0 0
- epoll
- epoll
- epoll
- epoll
- epoll
- epoll
- epoll
- epoll
- epoll
- epoll
- epoll
- epoll
- epoll
- epoll
- epoll
- epoll
- epoll
- epoll
- JavaScript 正则表达式对象RegExp test方法慎用/g
- @Autowired与@Resource的区别
- Listview使用BaseAdapter添加不同布局
- firefox 插件Tab Mix Plus配置截图
- MyBatis-动态SQL
- epoll
- 多线程笔记
- 标准化互信息NMI的实现源码。
- 互联网协议入门(二)
- 深入java集合学习系列-ConcurrentHashMap实现原理
- VISTA、Win Server 2008、Win7 等系统音频系统底层API
- thinkphp3.2【空操作和空控制器使用】
- 1016. 部分A+B (15)
- 使Eclipse下支持编写HTML/JS/CSS/JSP页面的自动提示