设为首页 加入收藏

TOP

IO多路复用(二) -- select、poll、epoll实现TCP反射程序(六)
2019-09-02 23:06:59 】 浏览:55
Tags:复用 select poll epoll 实现 TCP 反射 程序
nfd; //接受新的连接 if ((connfd = accept(this->listenfd, (struct sockaddr*)&cliaddr, &cliaddrlen)) == -1) { if (errno == EINTR) return false; else { perror("accept error:"); exit(1); } } fprintf(stdout, "accept a new client: %s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port); return add_event(connfd, EPOLLIN); //添加新的描述符 } void MyEpoll::client_do_multiplexing() { char sendline[MAXLINE], recvline[MAXLINE]; int n; int nready = -1; int i, fd; if (this->io_max < 2) { perror("please increase the max number of io!"); exit(1); } //添加连接描述符 if (!add_event(this->listenfd, POLLIN)) { perror("add event error!"); exit(1); } //添加标准输入描述符 if (!add_event(STDIN_FILENO, POLLIN)) { perror("add event error!"); exit(1); } while (1) { //等待事件产生 nready = wait_event(); if (-1 == nready) return; if (0 == nready) continue; for (i = 0; i < nready; i++) { fd = events[i].data.fd; //根据描述符的类型和事件类型进行处理 if ((fd == this->listenfd) && (events[i].events & EPOLLIN)) { //监听事件 n = read(this->listenfd, recvline, MAXLINE); if (n <= 0) { fprintf(stderr, "client: server is closed.\n"); close(this->listenfd); return; } write(STDOUT_FILENO, recvline, n); } else { n = read(STDIN_FILENO, sendline, MAXLINE); if (n <= 0) { shutdown(this->listenfd, SHUT_WR); continue; } write(this->listenfd, sendline, n); } } } } bool MyEpoll::add_event(int connfd, int event) { //将新的描述符添加到读描述符集合中 Epoll_event ev; ev.events = event; ev.data.fd = connfd; return epoll_ctl(this->epollfd, EPOLL_CTL_ADD, connfd, &ev) == 0; } void MyEpoll::handle_client_msg() { int i, fd; char buf[MAXLINE]; memset(buf, 0, MAXLINE); //处理信息 for (i = 0; i <= this->nready; i++) { fd = this->events[i].data.fd; if (fd == this->listenfd) continue; if (events[i].events & EPOLLIN) { int n = read(fd, buf, MAXLINE); if (n <= 0) { perror("read error:"); close(fd); delete_event(fd, EPOLLIN); } else { write(STDOUT_FILENO, buf, n); //向客户端发送buf write(fd, buf, strlen(buf)); } } } } int MyEpoll::wait_event() { /*开始轮询接收处理服务端和客户端套接字*/ int nready = epoll_wait(this->epollfd, this->events, this->io_max, INFTIM);; if (nready == -1) { fprintf(stderr, "poll error:%s.\n", strerror(errno)); } if (nready == 0) { fprintf(stdout, "poll is timeout.\n"); } return nready; } bool MyEpoll::delete_event(int fd, int state) { Epoll_event ev; ev.events = state; ev.data.fd = fd; return epoll_ctl(this->epollfd, EPOLL_CTL_DEL, fd, &ev) == 0; }

服务器代码

#include "multiplexing.h"

#define IPADDRESS   "127.0.0.1"
#define PORT        8787
#define LISTENQ     5
#define OPEN_MAX    1000

//函数声明
//创建套接字并进行绑定
static int socket_bind(const char* ip, int port);

int main(int argc, char *argv[]) {
    int listenfd = socket_bind(IPADDRESS, PORT);
    if (listenfd < 0) {
        perror("socket bind error");
        return 0;
    }

    listen(listenfd, LISTENQ);
    
    // 改动此处,调用不同的IO复用函数
    MySelect mltp(OPEN_MAX, listenfd);
    //MyPoll mltp(OPEN_MAX, listenfd);
    //MyEpoll mltp(OPEN_MAX, listenfd);
    
    mltp.server_do_multiplexing(); //处理服务端
    return 0;
}

static int socket_bind(const char* ip, int port) {
    int  listenfd;
    struct sockaddr_in servaddr;
    listenfd = socket(AF_INET, SOCK_STREAM, 0
首页 上一页 3 4 5 6 下一页 尾页 6/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇linux批量检测服务器能否ping通和.. 下一篇操作系统:进程的概念和与程序的..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目