epoll示范

来源:互联网 发布:mysql修改连接密码 编辑:程序博客网 时间:2024/06/08 16:23

一.server端

#include <iostream>#include <sys/socket.h>#include <sys/epoll.h>#include <netinet/in.h>#include <arpa/inet.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>using namespace std;#define MAXLINE 5#define OPEN_MAX 100#define LISTENQ 20#define SERV_PORT 5000#define INFTIM 1000void setnonblocking(int sock){    int opts;    opts = fcntl(sock, F_GETFL);    if(opts < 0)    {        perror("fcntl(sock,GETFL)");        exit(1);    }    opts = opts|O_NONBLOCK;    if(fcntl(sock, F_SETFL, opts) < 0)    {        perror("fcntl(sock,SETFL,opts)");        exit(1);    }   }int main(){int listenfd = socket(AF_INET, SOCK_STREAM, 0);//创建socketsetnonblocking(listenfd);//socket设置为非阻塞方式struct epoll_event ev; //ev用于注册事件struct epoll_event events[20];//events用于回传要处理的事件ev.data.fd = listenfd;//设置与要处理的事件相关的文件描述符ev.events = EPOLLIN|EPOLLET;//设置要处理的事件类型int epfd = epoll_create(256);//生成用于处理accept的epoll专用的文件描述符epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev);//注册epoll事件struct sockaddr_in clientaddr;struct sockaddr_in serveraddr;bzero(&serveraddr, sizeof(serveraddr));serveraddr.sin_family = AF_INET;char *local_addr = "127.0.0.1";    inet_aton(local_addr, &(serveraddr.sin_addr));    serveraddr.sin_port = htons(SERV_PORT);bind(listenfd, (sockaddr *)&serveraddr, sizeof(serveraddr));listen(listenfd, LISTENQ);int sockfd;ssize_t n;    char buf[MAXLINE];    socklen_t clilen;while(1){int nfds = epoll_wait(epfd, events, 20, 500);//等待epoll事件的发生for (int i = 0; i < nfds; i++){if (events[i].data.fd == listenfd){int connfd = accept(listenfd, (sockaddr *)&clientaddr, &clilen);if(connfd < 0){                    perror("connfd<0");                    exit(1);                }char *str = inet_ntoa(clientaddr.sin_addr);printf("accapt a connection from: %s\n", str);setnonblocking(connfd);//socket设置为非阻塞方式ev.data.fd = connfd;//设置用于读操作的文件描述符ev.events = EPOLLIN|EPOLLET;//设置用于注册的读操作事件epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);//注册ev}else if (events[i].events & EPOLLIN){if ((sockfd = events[i].data.fd) < 0){continue;}if ((n = read(sockfd, buf, MAXLINE)) < 0){if (errno == ECONNRESET){close(sockfd);events[i].data.fd = -1;}}else if (n == 0){close(sockfd);                    events[i].data.fd = -1;}buf[n] = '\0';ev.data.fd = sockfd;//设置用于写操作的文件描述符ev.events = EPOLLOUT|EPOLLET;////设置用于注册的写操作事件epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);//修改sockfd上要处理的事件为EPOLLOUTprintf("recv data:%s\n", buf);}else if (events[i].events&EPOLLOUT)            {   if ((sockfd = events[i].data.fd) < 0){continue;}write(sockfd, buf, n);ev.data.fd = sockfd;//设置用于读操作的文件描述符ev.events = EPOLLIN|EPOLLET;//设置用于注册的读操作事件epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);////修改sockfd上要处理的事件为EPOLINprintf("send data:%s\n", buf);            }}}return 0;}


二.client端

#include <iostream>#include <sys/socket.h>#include <sys/epoll.h>#include <netinet/in.h>#include <arpa/inet.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>using namespace std;#define SERV_PORT 5000#define MAXLINE 5#define MESSAGE "hello"int main(){char buf[MAXLINE];int sockfd = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in serveraddr;bzero(&serveraddr, sizeof(serveraddr));serveraddr.sin_family = AF_INET;char *local_addr = "127.0.0.1";    inet_aton(local_addr, &(serveraddr.sin_addr));    serveraddr.sin_port = htons(SERV_PORT);if (0 != connect(sockfd, (sockaddr *)&serveraddr, sizeof(serveraddr)))    {        printf("connected failed");        return 1;    }write(sockfd, MESSAGE, sizeof(MESSAGE));    int count = read(sockfd, buf, MAXLINE);    printf("Response from server: %s\n",buf);    close(sockfd);    return 0;}

0 0
原创粉丝点击