epoll简化版本

编程技术  /  houtizong 发布于 3年前   97
epoll基于socket
先上socket服务端
#include <stdio.h>#include <sys/socket.h>#include <arpa/inet.h>#include <stdlib.h>#include <string.h> #include <unistd.h>#include <netinet/in.h>#define MAXPENDING 5    /* Max connection requests */#define BUFFSIZE 32void Die(char *mess) { perror(mess); exit(1); }void HandleClient(int sock) {char buffer[BUFFSIZE];int received = -1;if ((received = recv(sock, buffer, BUFFSIZE, 0)) < 0) {Die("Failed to receive initial bytes from client");}while (received > 0) {if (send(sock, buffer, received, 0) != received) {Die("Failed to send bytes to client");}if ((received = recv(sock, buffer, BUFFSIZE, 0)) < 0) {Die("Failed to receive additional bytes from client");}}close(sock);}int main(int argc, char *argv[]) {        int serversock, clientsock;        struct sockaddr_in echoserver, echoclient;        if (argc != 2) {          fprintf(stderr, "USAGE: echoserver <port>\n");          exit(1);        }        if ((serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {          Die("Failed to create socket");        }        memset(&echoserver, 0, sizeof(echoserver));       /* Clear struct */        echoserver.sin_family = AF_INET;                  /* Internet/IP */        echoserver.sin_addr.s_addr = htonl(INADDR_ANY);   /* Incoming addr */        echoserver.sin_port = htons(atoi(argv[1]));       /* server port */if (bind(serversock, (struct sockaddr *) &echoserver,sizeof(echoserver)) < 0) { /* Bind the server socket */Die("Failed to bind the server socket");}if (listen(serversock, MAXPENDING) < 0) {/* Listen on the server socket */Die("Failed to listen on server socket");}while (1) {unsigned int clientlen = sizeof(echoclient);if ((clientsock =accept(serversock, (struct sockaddr *) &echoclient,&clientlen)) < 0) {/* Wait for client connection */Die("Failed to accept client connection");}fprintf(stdout, "Client connected: %s\n",inet_ntoa(echoclient.sin_addr));HandleClient(clientsock);}}


client
#include <stdio.h>#include <sys/socket.h>#include <arpa/inet.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <netinet/in.h>#define BUFFSIZE 32void Die(char *mess) {perror(mess);exit(1);}int main(int argc, char *argv[]) {int sock;struct sockaddr_in echoserver;char buffer[BUFFSIZE];unsigned int echolen;int received = 0;if (argc != 4) {fprintf(stderr, "USAGE: TCPecho <server_ip> <word> <port>\n");exit(1);}if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {Die("Failed to create socket");}    memset(&echoserver, 0, sizeof(echoserver));       /* Clear struct */    echoserver.sin_family = AF_INET;                  /* Internet/IP */    echoserver.sin_addr.s_addr = inet_addr(argv[1]);  /* IP address */    echoserver.sin_port = htons(atoi(argv[3]));       /* server port */    if (connect(sock,(struct sockaddr *) &echoserver,sizeof(echoserver)) < 0) {      Die("Failed to connect with server");    }    echolen = strlen(argv[2]);    if (send(sock, argv[2], echolen, 0) != echolen) {      Die("Mismatch in number of sent bytes");    }    fprintf(stdout, "Received: ");/* Receive the word back from the server */    while (received < echolen) {      int bytes = 0;      if ((bytes = recv(sock, buffer, BUFFSIZE-1, 0)) < 1) {        Die("Failed to receive bytes from server");      }      received += bytes;      buffer[bytes] = '\0'; /* Assure null terminated string */      fprintf(stdout, buffer);    }    fprintf(stdout, "\n");    close(sock);    exit(0);    }            

epoll在这个基础上改造一下
epolltest.c
#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 <errno.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);//apue第三章讲了    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 i, maxi, listenfd, connfd, sockfd,epfd,nfds;    ssize_t n;    char line[MAXLINE];    socklen_t clilen;    struct epoll_event ev,events[20];//声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件    epfd=epoll_create(256);//生成用于处理accept的epoll专用的文件描述符    struct sockaddr_in clientaddr,serveraddr;    listenfd = socket(AF_INET, SOCK_STREAM, 0);      //setnonblocking(listenfd);//把socket设置为非阻塞方式      ev.data.fd=listenfd;//设置与要处理的事件相关的文件描述符    ev.events=EPOLLIN|EPOLLET;//ev.events=EPOLLIN;       epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);//注册epoll事件,EPOLL_CTL_ADD    bzero(&serveraddr, sizeof(serveraddr));//memset(&echoserver, 0, sizeof(echoserver));    serveraddr.sin_family = AF_INET;    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);//char *local_addr="192.168.229.129";inet_aton(local_addr,&(serveraddr.sin_addr));    serveraddr.sin_port=htons(SERV_PORT);    bind(listenfd,(sockaddr *)&serveraddr, sizeof(serveraddr));    listen(listenfd, LISTENQ);    maxi = 0;    while(1){//for ( ; ; ) {            nfds=epoll_wait(epfd,events,20,500);//等待epoll事件的发生            for(i=0;i<nfds;++i){            if(events[i].data.fd==listenfd){                connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen);                if(connfd<0){                    perror("connfd<0");                    exit(1);                }                //setnonblocking(connfd);                char *str = inet_ntoa(clientaddr.sin_addr);                cout << "accapt a connection from " << str << endl;                 ev.data.fd=connfd;//设置用于读操作的文件描述符                ev.events=EPOLLIN|EPOLLET; //ev.events=EPOLLIN;//设置用于注测的读操作事件                epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);//注册ev            }else if(events[i].events&EPOLLIN){                cout << "EPOLLIN" << endl;                if ( (sockfd = events[i].data.fd) < 0) continue;                if ((n = read(sockfd, line, MAXLINE)) < 0) {                    if (errno == ECONNRESET) {                        close(sockfd);                        events[i].data.fd = -1;                    } else{                        std::cout<<"readline error"<<std::endl;                    }                } else if (n == 0) {                    close(sockfd);                    events[i].data.fd = -1;                }                line[n] = '\0';                cout << "read " << line << endl;                ev.data.fd=sockfd;//描述符                   ev.events=EPOLLOUT|EPOLLET;//设置用于注测的写操作事件 //修改sockfd上要处理的事件为EPOLLOUT //epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);            }else if(events[i].events&EPOLLOUT){                   sockfd = events[i].data.fd;                write(sockfd, line, n);                ev.data.fd=sockfd;//设置用于读操作的文件描述符                ev.events=EPOLLIN|EPOLLET;//设置用于注测的读操作事件                epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);//修改sockfd上要处理的事件为EPOLIN            }        }    }    return 0;}

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客