《linux高性能服务器编程》 p183示例 epoll实现
示例中服务端和客户端都使用了使用poll调用做io复用,我用epoll重写服务端代码,同时尽可能的用了c++风格。。。
有些地方可能实现的很累赘,还请各位不吝赐教,这个小项目就权当是熟悉poll和epoll了。
- 服务端代码:
/*
code for server
*/
#define _GNU_SOURCE 1
#include<iostream>
#include<string>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<assert.h>
#include<unistd.h>
#include<errno.h>
#include<cstring>
#include<fcntl.h>
#include<cstdlib>
#include<sys/epoll.h>
#include<vector>
#include<map>
const int USER_LIMIT = 5;
const int BUFFER_SIZE = 64;
const int FD_LIMIT = 65535;
const int MAX_EVENT_NUMBER = 1024;
//标识每一个连入的客户
struct client_data{
sockaddr_in address; //地址
char *write_buf; //写缓存,记录客户的输入
char buf[BUFFER_SIZE]; //记录需要向该客户发送的数据
int fd; //标识文件描述符
};
int setnonblocking(int fd){
int old_option = fcntl(fd, F_GETFL);
int new_option = old_option | O_NONBLOCK;
fcntl(fd, F_SETFL, new_option);
return old_option;
}
int main()
{
using namespace std;
int ret = 0;
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = htons(INADDR_ANY);
address.sin_port = htons(12345);
int listenfd = socket(PF_INET, SOCK_STREAM, 0);
assert(listenfd != -1);
ret = bind(listenfd, reinterpret_cast<struct sockaddr*>(&address), sizeof(address));
assert(ret != -1);
ret = listen(listenfd, 5);
assert(ret != -1);
vector<struct client_data> users;
map<int, int> fdToUser; //为每一个接入的socket映射到唯一的客户数组索引
int epollFds = epoll_create(MAX_EVENT_NUMBER);
struct epoll_event event;
bzero