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
|