#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//stl head
#include //包含hash_map 的头文件
//#include //stl的map
using namespace std; //std 命名空间
using namespace __gnu_cxx; //而hash_map是在__gnu_cxx的命名空间里的
int init_thread_pool(int threadNum);
void *epoll_loop(void* para);
void *check_connect_timeout(void* para);
struct sockStruct
{
time_t time;
char name[32];
char *recvBuf;
};
//hash-map
//hash_map sock_map;
hash_map sock_map;
#define MAXRECVBUF 4096
#define MAXBUF MAXRECVBUF+10
int fd_Setnonblocking(int fd)
{
int op;
op=fcntl(fd,F_GETFL,0);
fcntl(fd,F_SETFL,op|O_NONBLOCK);
return op;
}
void on_sigint(int signal)
{
exit(0);
}
int listenfd;
int sock_op=1;
struct sockaddr_in address;
struct epoll_event event0;
#define MAX_CNT 2000
struct epoll_event events[MAX_CNT];
int epfd;
int main(int argc,char* argv[])
{
struct rlimit rlim;
rlim.rlim_cur = 20480;
rlim.rlim_max = 20480;
if (setrlimit(RLIMIT_NOFILE, &rlim) != 0)
{
perror("setrlimit error.\n");
return -1;
}
else
{
printf("setrlimit right.\n");
}
int connType = 1;
if (argc > 1)
{
connType = atoi(argv[1]);
printf("usage epoll2client 1/2 1:long-time connections, 2:short-time connections\n");
}
init_thread_pool(4);
signal(SIGPIPE,SIG_IGN);
signal(SIGCHLD,SIG_IGN);
signal(SIGINT,&on_sigint);
struct sockaddr_in serv_addr;
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(9300);
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
bzero(&(serv_addr.sin_zero), 8);
epfd=epoll_create(65535);
memset(&event0,0,sizeof(event0));
event0.data.fd=listenfd;
event0.events=EPOLLIN|EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&event0);
/* Init */
//clock_t start, end;
//start = clock();
//printf("time calc test\n");
struct timeval start, end; // define 2 struct timeval variables
//-------------------------
gettimeofday(&start, NULL); // get the beginning time
//-------------------------
int max_count = 0;
int sockfd = 0;
for (int i=0;i 0?printf("epoll_wait n = %d\n", n):0;
for (int i = 0; i < n; ++i)
{
if (events[i].events&EPOLLIN)
{
//handle_message(events[i].data.fd);
int ret = 0;
int rs = 1;
while (rs)
{
ret = recv(events[i].data.fd, recvBuf, 1024, 0);
if (ret < 0)
{
if (errno == EAGAIN)
{
break;
}
else {
events[i].events = EPOLLIN | EPOLLOUT;
epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, &events[i]);
close(events[i].data.fd);
break;
}
}
else if (ret == sizeof(recvBuf))
rs = 1;
else
rs = 0;
}
if (ret > 0)
{
printf("fd:%d recv:%s\n", events[i].data.fd, recvBuf);
}
}
else if (events[i].events&EPOLLOUT)
{
time_t timer = time(NULL);
strftime(szBuf, sizeof(szBuf), "%Y-%m-%d %H:%M:%S", localtime(&timer));
sprintf(sendBuf, "HTTP/1.0 200 OK\r\nContent-type: text/plain\r\ntime:%s\r\ndeviceName:Unit%04d\r\n",
szBuf, events[i].data.fd);
send(events[i].data.fd, sendBuf, strlen(sendBuf)+1, 0);
events[i].events = EPOLLOUT; //EPOLLOUT | EPOLLET
epoll_ctl(epfd, EPOLL_CTL_ADD, events[i].data.fd, &events[i]);
//close(events[i].data.fd);
usleep(3*1000);//3ms
}
else
{
events[i].events = EPOLLIN | EPOLLOUT;
epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, &events[i]);
close(events[i].data.fd);
}
}
}
return 0;
}
#define CNN_TMOUT_SEC 60
void *check_connect_timeout(void* para)
{
hash_map::iterator it_find;
for(it_find = sock_map.begin(); it_find!=sock_map.end(); ++it_find){
if( time((time_t*)0) - (it_find->second).time > CNN_TMOUT_SEC){
free((it_find->second).recvBuf);
sock_map.erase(it_find);
printf("name:%s fd:%d timeout, close it.\n", (it_find->second).name, it_find->first);
close(it_find->first);
}
}
//loop time
sleep(CNN_TMOUT_SEC);
return NULL;
}