epoll server client

来源:互联网 发布:java运算符是什么类型 编辑:程序博客网 时间:2024/05/22 08:26

服务器端:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <netinet/in.h>#include <sys/socket.h>#include <arpa/inet.h>#include <sys/epoll.h>#include <unistd.h>#include <sys/types.h>#define IPADDRESS   "127.0.0.1"#define PORT        8787#define MAXSIZE     1024#define LISTENQ     5#define FDSIZE      1000#define EPOLLEVENTS 100//函数声明//创建套接字并进行绑定static int socket_bind(const char *ip, int port);//IO多路复用epollstatic void do_epoll(int listenfd);//事件处理函数static void        handle_events(int epollfd, struct epoll_event *events, int num, int listenfd, char *buf);//处理接收到的连接static void handle_accpet(int epollfd, int listenfd);//读处理static void do_read(int epollfd, int fd, char *buf);//写处理static void do_write(int epollfd, int fd, char *buf);//添加事件static void add_event(int epollfd, int fd, int state);//修改事件static void modify_event(int epollfd, int fd, int state);//删除事件static void delete_event(int epollfd, int fd, int state);int main(int argc, char *argv[]) {    int listenfd;    listenfd = socket_bind(IPADDRESS, PORT);    listen(listenfd, LISTENQ);    do_epoll(listenfd);    return 0;}static int socket_bind(const char *ip, int port) {    int listenfd;    struct sockaddr_in servaddr;    listenfd = socket(AF_INET, SOCK_STREAM, 0);    if (listenfd == -1) {        perror("socket error:");        exit(1);    }    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family = AF_INET;    inet_pton(AF_INET, ip, &servaddr.sin_addr); // net to local inet_pton:将点分十进制> “二进制整数    servaddr.sin_port = htons(port); // 大端(Big Endian):即网络字节序。小端(Littile Endian):即主机字节序。    if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) == -1) {        perror("bind error: ");        exit(1);    }    return listenfd;}static void do_epoll(int listenfd) {    int epollfd;    struct epoll_event events[EPOLLEVENTS];    int ret;    char buf[MAXSIZE];    memset(buf, 0, MAXSIZE);    //创建一个描述符    epollfd = epoll_create(FDSIZE);    //添加监听描述符事件    add_event(epollfd, listenfd, EPOLLIN);    for (; ;) {        printf("server do_epoll>>>>\n");        //获取已经准备好的描述符事件        ret = epoll_wait(epollfd, events, EPOLLEVENTS, -1);        handle_events(epollfd, events, ret, listenfd, buf);    }    close(epollfd);}static voidhandle_events(int epollfd, struct epoll_event *events, int num, int listenfd, char *buf) {    int i;    int fd;    //进行选好遍历    for (i = 0; i < num; i++) {        fd = events[i].data.fd;        //根据描述符的类型和事件类型进行处理        printf("handle event poll num, fd, listenfd %d, %d, %d, events:%d \n", num, fd, listenfd, events[i].events);        if ((fd == listenfd) && (events[i].events & EPOLLIN))            handle_accpet(epollfd, listenfd);        else if (events[i].events & EPOLLIN)            do_read(epollfd, fd, buf);        else if (events[i].events & EPOLLOUT)            do_write(epollfd, fd, buf);    }}static void handle_accpet(int epollfd, int listenfd) {    int clifd;    struct sockaddr_in cliaddr;    socklen_t cliaddrlen;    clifd = accept(listenfd, (struct sockaddr *) &cliaddr, &cliaddrlen);    if (clifd == -1)        perror("accpet error:");    else {        printf("accept a new client: %s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);        //添加一个客户描述符和事件        add_event(epollfd, clifd, EPOLLIN);    }}static void do_read(int epollfd, int fd, char *buf) {    int nread;    nread = read(fd, buf, MAXSIZE);    if (nread == -1) {        perror("read error:");        close(fd);        delete_event(epollfd, fd, EPOLLIN);    }    else if (nread == 0) {        fprintf(stderr, "client close.\n");        close(fd);        delete_event(epollfd, fd, EPOLLIN);    }    else {        printf("read message is : %s", buf);        //修改描述符对应的事件,由读改为写        modify_event(epollfd, fd, EPOLLOUT);    }}static void do_write(int epollfd, int fd, char *buf) {    int nwrite;    nwrite = write(fd, buf, strlen(buf));    printf("do_write message is : %s", buf);    if (nwrite == -1) {        perror("write error:");        close(fd);        delete_event(epollfd, fd, EPOLLOUT);    } else {        modify_event(epollfd, fd, EPOLLIN);    }    memset(buf, 0, MAXSIZE);}static void add_event(int epollfd, int fd, int state) {    struct epoll_event ev;    ev.events = state;    ev.data.fd = fd;    epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev);}static void delete_event(int epollfd, int fd, int state) {    struct epoll_event ev;    ev.events = state;    ev.data.fd = fd;    epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &ev);}static void modify_event(int epollfd, int fd, int state) {    struct epoll_event ev;    ev.events = state;    ev.data.fd = fd;    epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &ev);}


客户端:

#include <netinet/in.h>#include <sys/socket.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/epoll.h>#include <time.h>#include <unistd.h>#include <sys/types.h>#include <arpa/inet.h>#define MAXSIZE     1024#define IPADDRESS   "127.0.0.1"#define SERV_PORT   8787#define FDSIZE        1024#define EPOLLEVENTS 20static void handle_connection(int sockfd);static void handle_events(int epollfd, struct epoll_event *events, int num, int sockfd, char *buf);static void do_read(int epollfd, int fd, int sockfd, char *buf);static void do_read(int epollfd, int fd, int sockfd, char *buf);static void do_write(int epollfd, int fd, int sockfd, char *buf);static void add_event(int epollfd, int fd, int state);static void delete_event(int epollfd, int fd, int state);static void modify_event(int epollfd, int fd, int state);int main(int argc, char *argv[]) {    int sockfd;    struct sockaddr_in servaddr;    sockfd = socket(AF_INET, SOCK_STREAM, 0);    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(SERV_PORT);    inet_pton(AF_INET, IPADDRESS, &servaddr.sin_addr);    connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));    //处理连接    handle_connection(sockfd);    close(sockfd);    return 0;}static void handle_connection(int sockfd) {    int epollfd;    struct epoll_event events[EPOLLEVENTS];    char buf[MAXSIZE];    int ret;    epollfd = epoll_create(FDSIZE);    add_event(epollfd, STDIN_FILENO, EPOLLIN);    for (; ;) {        printf("handle_connection>>>>>%s", buf);        ret = epoll_wait(epollfd, events, EPOLLEVENTS, -1);        //bzero(buf, sizeof(buf));        handle_events(epollfd, events, ret, sockfd, buf);    }    close(epollfd);}static voidhandle_events(int epollfd, struct epoll_event *events, int num, int sockfd, char *buf) {    int fd;    int i;    for (i = 0; i < num; i++) {        fd = events[i].data.fd;        if (events[i].events & EPOLLIN) {  // has input action ....            //只有当对端有数据写入时才会触发>            printf("listner the some thing has writed>%s", buf);            do_read(epollfd, fd, sockfd, buf);        }else if (events[i].events & EPOLLOUT) {//            对端读取了一些数据,"//                    "又重新可写了 简单地说:EPOLLOUT事件只有在不可写到"//                    "可写的转变时刻,才会触发一次,所以叫边缘触发>>            printf("listner the some thing has writed >%s", buf);            do_write(epollfd, fd, sockfd, buf);        }    }}static void do_read(int epollfd, int fd, int sockfd, char *buf) {    int nread;    nread = read(fd, buf, MAXSIZE); // from the stdin read the input    if (nread == -1) {        perror("read error:");        close(fd);    }    else if (nread == 0) {        fprintf(stderr, "server close.\n");        close(fd);    }    else {        if (fd == STDIN_FILENO){ // add the epollout action            printf("do read stdin:%d, %s\n", fd, buf);            add_event(epollfd, sockfd, EPOLLOUT);        }else {            printf("receive the data from the other:%s\n", buf);            delete_event(epollfd, sockfd, EPOLLIN); //            add_event(epollfd, STDOUT_FILENO, EPOLLOUT);        }    }}static void do_write(int epollfd, int fd, int sockfd, char *buf) {    int nwrite;    nwrite = write(fd, buf, strlen(buf));    if (nwrite == -1) {        perror("write error:");        close(fd);    }else {        printf("do do_write:%d, data:%s\n", fd, buf);        if (fd == STDOUT_FILENO){            delete_event(epollfd, fd, EPOLLOUT);        } else{            modify_event(epollfd, fd, EPOLLIN);        }    }    memset(buf, 0, MAXSIZE);}static void add_event(int epollfd, int fd, int state) {    struct epoll_event ev;    ev.events = state;    ev.data.fd = fd;    epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev);}static void delete_event(int epollfd, int fd, int state) {    struct epoll_event ev;    ev.events = state;    ev.data.fd = fd;    epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &ev);}static void modify_event(int epollfd, int fd, int state) {    struct epoll_event ev;    ev.events = state;    ev.data.fd = fd;    epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &ev);}