epoll简化版本

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 32
void 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 32
void 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 1000
void 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;
}

你可能感兴趣的:(epoll)