- 论坛徽章:
- 0
|
本帖最后由 w1964332 于 2014-02-18 22:50 编辑
代码如下:
#include <iostream>
#include <sys/socket.h>
#include <sys/unistd.h>
#include <sys/epoll.h>
#include <errno.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
using namespace std;
#define unsigned short ushort;
#define unix_error(s) do{ perror(s);printf("errno:%d\n",errno);} while(0)
//#define void *(*handle)(void *)
/*
typedef struct _fd_event{
int fd; //client fd
handle func; //callback function
int type; //event type , read ,wrte
}fd_event;*/
bool set_nonblock(int fd){
int opt;
opt = fcntl(fd, F_GETFL);
if(opt < 0){
unix_error("get file status");
return false;
}
opt = fcntl(fd, F_SETFL, opt | O_NONBLOCK);
if(opt <0){
unix_error("set file status");
return false;
}
return true;
}
class Epoll_server{
public:
Epoll_server();
Epoll_server(const char *ip, const ushort uport, int timeout_, int max_event_);
void run();
static void* process_connect(void *p);
void process_event(struct epoll_event *event);
void add_event();
int s_fd; //server fd
set<int> client_set;
int nfds; //epoll fd
private:
char ipaddr[20]; //server ip
ushort port; //server port
int timeout;
int max_event;
char buf[1000];
};
Epoll_server::Epoll_server(){
}
Epoll_server::Epoll_server(const char *ip, const ushort port_, int timeout_, int max_event_){
strncpy(ipaddr, ip, 20);
port = port_;
timeout = timeout_;
max_event = max_event_;
memset(buf, 0, 1000);
}
void Epoll_server::run(){
nfds = epoll_create(1);
s_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
if(s_fd < 0) {unix_error("socket");}
/*
struct sockaddr_in addr_in;
bzero(&addr_in, sizeof(struct sockaddr));
addr_in.sin_family = AF_INET;
struct in_addr addr;
addr_in.sin_addr.s_addr = inet_addr(ipaddr);
addr_in.sin_port = htons(port);*/
sockaddr_in listen_addr;
listen_addr.sin_family=AF_INET;
listen_addr.sin_port=htons ( port );
listen_addr.sin_addr.s_addr=htonl(INADDR_ANY);
//listen_addr.sin_addr.s_addr=inet_addr(ipaddr);
socklen_t sock_size = sizeof(struct sockaddr);
int reuse = 1; //support port to reuse
// setsockopt(s_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
if( -1 == bind(s_fd, (sockaddr *)&listen_addr, sizeof(listen_addr))){
unix_error("bind");
exit(1);
}
if(-1 == listen(s_fd, 20)){
unix_error("listen");
exit(1);
}
pthread_t pthid;
pthread_create(&pthid, NULL, process_connect, this);
struct epoll_event events[max_event];
int n = 0;
while(1){
printf("wait\n");
n = epoll_wait(nfds, events, max_event, timeout);
if(n == 0 ) continue;
for(int i = 0 ; i < n; i++){
process_event(events+i);
}
}
}
void *Epoll_server::process_connect(void *p){
Epoll_server *p_epoll = (Epoll_server *)p;
int fd = p_epoll->s_fd;
int clientfd;
struct sockaddr addr;
socklen_t len;
struct epoll_event event;
while(1){
memset(&addr , 0, sizeof(sizeof(struct sockaddr)));
if(-1 == (clientfd = accept(fd, &addr, &len))){
unix_error("accept");
continue;
}
if(false == set_nonblock(clientfd)) continue;
p_epoll->client_set.insert(clientfd);
// event.events = EPOLLIN || EPOLLET;
event.events = EPOLLIN;
event.data.fd = clientfd;
epoll_ctl(p_epoll->nfds, EPOLL_CTL_ADD, clientfd, &event);
}
}
void Epoll_server::process_event(struct epoll_event *pevent){
if(pevent->events & EPOLLIN){
recv(pevent->data.fd, buf, 1000, 0);
pevent->events = EPOLLOUT;
epoll_ctl(nfds, EPOLL_CTL_MOD, pevent->data.fd,pevent);
}else if(pevent->events & EPOLLOUT){
send(pevent->data.fd, "hello", 5, 0);
pevent->events = EPOLLIN;
epoll_ctl(nfds, EPOLL_CTL_MOD, pevent->data.fd, pevent);
}else{
close(pevent->data.fd);
epoll_ctl(nfds, EPOLL_CTL_DEL,pevent->data.fd, NULL);
}
}
void Epoll_server::add_event(){
}
int main(int argc, char **argv){
Epoll_server server("192.168.1.1", 10001, 1000, 20);
server.run();
return 0;
}
大神们能帮忙分析下问题吗? |
|