#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <iostream>
#include <pthread.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <iostream>
#include <pthread.h>
using namespace std;
#define MAX_EVENTS 100000
#define MAX_EVENTS 100000
pthread_mutex_t mutex;
pthread_cond_t cond1;
pthread_mutex_t mutex2;
pthread_cond_t cond2;
int listenFd;
pthread_cond_t cond1;
pthread_mutex_t mutex2;
pthread_cond_t cond2;
int listenFd;
struct task_s
{
int fd;
int type;//新链接 , 接收数据, 发送数据
task_s* pNext;
task_s* pPrepNext;
};
{
int fd;
int type;//新链接 , 接收数据, 发送数据
task_s* pNext;
task_s* pPrepNext;
};
struct user_data {
int fd;
unsigned int n_size;
char line[1024];
};
int fd;
unsigned int n_size;
char line[1024];
};
int g_epollFd;
void InitListenSocket(int epollFd, short port)
{
listenFd = socket(AF_INET, SOCK_STREAM, 0);
fcntl(listenFd, F_SETFL, O_NONBLOCK); // set non-blocking
printf("server listen fd=%d\n", listenFd);
{
listenFd = socket(AF_INET, SOCK_STREAM, 0);
fcntl(listenFd, F_SETFL, O_NONBLOCK); // set non-blocking
printf("server listen fd=%d\n", listenFd);
struct epoll_event epv = { 0,{ 0 } };
int op = EPOLL_CTL_ADD;
epv.data.ptr = NULL;
epv.data.fd = listenFd;
epv.events = EPOLLIN;
int op = EPOLL_CTL_ADD;
epv.data.ptr = NULL;
epv.data.fd = listenFd;
epv.events = EPOLLIN;
if (epoll_ctl(epollFd, op, listenFd, &epv) < 0)
printf("Event Add failed[fd=%d],\n", listenFd);
else
printf("Event Add OK[fd=%d], op=%d,\n", listenFd, op);
printf("Event Add failed[fd=%d],\n", listenFd);
else
printf("Event Add OK[fd=%d], op=%d,\n", listenFd, op);
sockaddr_in sin;
bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(port);
bind(listenFd, (const sockaddr*)&sin, sizeof(sin));
listen(listenFd, 50000);
}
bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(port);
bind(listenFd, (const sockaddr*)&sin, sizeof(sin));
listen(listenFd, 50000);
}
static int count111 = 0;
static time_t oldtime = 0, nowtime = 0;
task_s* readhead = NULL;
task_s* readtail = NULL;
static time_t oldtime = 0, nowtime = 0;
task_s* readhead = NULL;
task_s* readtail = NULL;
task_s* accepthead = NULL;
task_s* accepttail = NULL;
task_s* accepttail = NULL;
void* readtask(void *args)
{
{
int fd = -1;
unsigned int n = 0;
//用于把读出来的数据传递出去
unsigned int n = 0;
//用于把读出来的数据传递出去
struct user_data *data = NULL;
while (1)
{
pthread_mutex_lock(&mutex);
//等待到任务队列不为空
while (1)
{
pthread_mutex_lock(&mutex);
//等待到任务队列不为空
//while (readhead == NULL)
// pthread_cond_wait(&cond1, &mutex);
// pthread_cond_wait(&cond1, &mutex);
//从任务队列取出一个读任务
struct task_s *tmp = readhead;
struct task_s *tmp = readhead;
if (readhead != NULL)
{
fd = readhead->fd;
readhead = readhead->pNext;
//printf(" accept, seq: %d \n", tmp->type);
delete tmp;
}
else
{
pthread_mutex_unlock(&mutex);
usleep(1000 * 100);
continue;
}
pthread_mutex_unlock(&mutex);
{
fd = readhead->fd;
readhead = readhead->pNext;
//printf(" accept, seq: %d \n", tmp->type);
delete tmp;
}
else
{
pthread_mutex_unlock(&mutex);
usleep(1000 * 100);
continue;
}
pthread_mutex_unlock(&mutex);
data = new user_data();
data->fd = fd;
char recvBuf[1024] = { 0 };
int ret = 999;
int rs = 1;
int ret = 999;
int rs = 1;
while (rs)
{
ret = recv(fd, recvBuf, 1024, 0);// 接受客户端消息
{
ret = recv(fd, recvBuf, 1024, 0);// 接受客户端消息
if (ret < 0)
{
//由于是非阻塞的模式,所以当errno为EAGAIN时,表示当前缓冲区已无数据可//读在这里就当作是该次事件已处理过。
{
//由于是非阻塞的模式,所以当errno为EAGAIN时,表示当前缓冲区已无数据可//读在这里就当作是该次事件已处理过。
if (errno == EAGAIN)
{
printf("EAGAIN\n");
break;
}
else {
printf("recv error! fd: %d\n", fd);
struct epoll_event epv = { 0,{ 0 } };
epv.data.ptr = NULL;
epoll_ctl(g_epollFd, EPOLL_CTL_DEL, fd, &epv);
close(fd);
rs = 0;
break;
}
}
else if (ret == 0)
{
// 这里表示对端的socket已正常关闭.?
{
printf("EAGAIN\n");
break;
}
else {
printf("recv error! fd: %d\n", fd);
struct epoll_event epv = { 0,{ 0 } };
epv.data.ptr = NULL;
epoll_ctl(g_epollFd, EPOLL_CTL_DEL, fd, &epv);
close(fd);
rs = 0;
break;
}
}
else if (ret == 0)
{
// 这里表示对端的socket已正常关闭.?
struct epoll_event epv = { 0,{ 0 } };
epv.data.ptr = NULL;
epoll_ctl(g_epollFd, EPOLL_CTL_DEL, fd, &epv);
rs = 0;
close(fd);
}
if (ret == sizeof(recvBuf))
rs = 1;// 需要再次读取
else
rs = 0;
}
if (ret>0) {
epv.data.ptr = NULL;
epoll_ctl(g_epollFd, EPOLL_CTL_DEL, fd, &epv);
rs = 0;
close(fd);
}
if (ret == sizeof(recvBuf))
rs = 1;// 需要再次读取
else
rs = 0;
}
if (ret>0) {
data->n_size = n;
count111++;
count111++;
struct tm *today;
time_t ltime;
time(&nowtime);
time_t ltime;
time(&nowtime);
if (nowtime != oldtime) {
printf("%d\n", count111);
oldtime = nowtime;
count111 = 0;
}
printf("%d\n", count111);
oldtime = nowtime;
count111 = 0;
}
char buf[1000] = { 0 };
sprintf(buf, "HTTP/1.0 200 OK\r\nContent-type: text/plain\r\n\r\n%s", "Hello world!\n");
send(fd, buf, strlen(buf), 0);
//
}
}
}
sprintf(buf, "HTTP/1.0 200 OK\r\nContent-type: text/plain\r\n\r\n%s", "Hello world!\n");
send(fd, buf, strlen(buf), 0);
//
}
}
}
void * writetask(void *args);
int accepttask(void *args)
{
struct sockaddr_in sin;
socklen_t len = sizeof(struct sockaddr_in);
int nfd, i;
{
struct sockaddr_in sin;
socklen_t len = sizeof(struct sockaddr_in);
int nfd, i;
int events;
// accept
if ((nfd = accept(listenFd, (struct sockaddr*)&sin, &len)) == -1)
{
if (errno != EAGAIN && errno != EINTR)
{
}
printf("%s: accept error!!! , %d", __func__, errno);
usleep(1000);
return 0;
}
do
{
// accept
if ((nfd = accept(listenFd, (struct sockaddr*)&sin, &len)) == -1)
{
if (errno != EAGAIN && errno != EINTR)
{
}
printf("%s: accept error!!! , %d", __func__, errno);
usleep(1000);
return 0;
}
do
{
// set nonblocking
int iret = 0;
if ((iret = fcntl(nfd, F_SETFL, O_NONBLOCK)) < 0)
{
printf("%s: fcntl nonblocking failed:%d", __func__, iret);
break;
}
// add a read event for receive data?
struct epoll_event epv = { 0,{ 0 } };
int op = EPOLL_CTL_ADD;
epv.data.ptr = NULL;
epv.events = EPOLLIN|EPOLLET;
epv.data.fd = nfd;
if (epoll_ctl(g_epollFd, op, nfd, &epv) < 0)
printf("Event Add failed[fd=%d], evnets[%d]\n", nfd, EPOLLIN);
else
printf("Event Add OK[fd=%d], op=%d, evnets[%0X]\n", nfd, op, EPOLLIN);
int iret = 0;
if ((iret = fcntl(nfd, F_SETFL, O_NONBLOCK)) < 0)
{
printf("%s: fcntl nonblocking failed:%d", __func__, iret);
break;
}
// add a read event for receive data?
struct epoll_event epv = { 0,{ 0 } };
int op = EPOLL_CTL_ADD;
epv.data.ptr = NULL;
epv.events = EPOLLIN|EPOLLET;
epv.data.fd = nfd;
if (epoll_ctl(g_epollFd, op, nfd, &epv) < 0)
printf("Event Add failed[fd=%d], evnets[%d]\n", nfd, EPOLLIN);
else
printf("Event Add OK[fd=%d], op=%d, evnets[%0X]\n", nfd, op, EPOLLIN);
} while (0);
printf("-----------------new conn[%s:%d], pos[%d]---------------\n", inet_ntoa(sin.sin_addr),
ntohs(sin.sin_port), i);
printf("-----------------new conn[%s:%d], pos[%d]---------------\n", inet_ntoa(sin.sin_addr),
ntohs(sin.sin_port), i);
return 0;
}
}
int main(int argc, char **argv)
{
unsigned short port = 9999; // default port?
if (argc == 2) {
port = atoi(argv[1]);
}
pthread_t tid1, tid2,tid3;
{
unsigned short port = 9999; // default port?
if (argc == 2) {
port = atoi(argv[1]);
}
pthread_t tid1, tid2,tid3;
// create epoll
g_epollFd = epoll_create(MAX_EVENTS);
if (g_epollFd <= 0) printf("create epoll failed.%d\n", g_epollFd);
// create & bind listen socket, and add to epoll, set non-blocking?
InitListenSocket(g_epollFd, port);
// event loop?
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond1, NULL);
g_epollFd = epoll_create(MAX_EVENTS);
if (g_epollFd <= 0) printf("create epoll failed.%d\n", g_epollFd);
// create & bind listen socket, and add to epoll, set non-blocking?
InitListenSocket(g_epollFd, port);
// event loop?
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond1, NULL);
pthread_create(&tid1, NULL, readtask, NULL);
pthread_create(&tid2, NULL, readtask, NULL);
//pthread_create(&tid3, NULL, accepttask, NULL);
//
struct epoll_event* pEvent = new epoll_event[MAX_EVENTS];
printf("server running:port[%d]\n", port);
pthread_create(&tid2, NULL, readtask, NULL);
//pthread_create(&tid3, NULL, accepttask, NULL);
//
struct epoll_event* pEvent = new epoll_event[MAX_EVENTS];
printf("server running:port[%d]\n", port);
int checkPos = 0;
int acceptSeq = 0;
int dataSeq = 0;
while (1) {
// a simple timeout check here, every time 100, better to use a mini-heap, and add timer event?
long now = time(NULL);
for (int i = 0; i < 100; i++, checkPos++) // doesn't check listen fd?
{
if (checkPos == MAX_EVENTS) checkPos = 0; // recycle
/*
long duration = now - g_Events[checkPos].last_active;
if (duration >= 60 * 3) // 60s timeout?
{
close(g_Events[checkPos].fd);
printf("[fd=%d] timeout[%d--%d].\n", g_Events[checkPos].fd, g_Events[checkPos].last_active, now);
//EventDel(g_epollFd, &g_Events[checkPos]);
struct epoll_event epv = { 0,{ 0 } };
epv.data.ptr = NULL;
epoll_ctl(g_epollFd, EPOLL_CTL_DEL, fd, &epv);
}*/
}
// wait for events to happen?
int fds = epoll_wait(g_epollFd, pEvent, MAX_EVENTS, 1000);
if (fds < 0) {
printf("epoll_wait error, exit\n");
break;
}
for (int i = 0; i < fds; i++) {
//myevent_s *ev = (struct myevent_s*)events[i].data.ptr;
if ((pEvent[i].events&EPOLLIN) && (pEvent[i].data.fd != listenFd)) // read event?
{
if (pEvent[i].data.fd < 0) continue;
task_s* pt = new task_s;
pt->fd = pEvent[i].data.fd;
pt->type = dataSeq++;
//printf("fds: %d i: %d listenFd: %d fd: %d \n", fds, i, listenFd, events[i].data.fd);
pt->pNext = NULL;
pthread_mutex_lock(&mutex);
if (readhead == NULL)
{
readhead = pt;
if(readtail == NULL)
readtail = pt;
}
else
{
readtail->pNext = pt;
readtail = pt;
}
//pthread_cond_broadcast(&cond1);
pthread_mutex_unlock(&mutex);
}
else if ((pEvent[i].events&EPOLLIN) && (pEvent[i].data.fd == listenFd))
{
acceptSeq++;
printf("fds: %d i: %d listenFd: %d fd: %d : acceptSeq: %d \n", fds, i, listenFd, pEvent[i].data.fd, acceptSeq);
accepttask(NULL);
}
if (pEvent[i].events&EPOLLOUT) // write event?
{
//ev->call_back(ev->fd, events[i].events, ev->arg);
//task_s* pt = new task_s;
//pt->fd = events[i].data.fd;
//pt->type = 2;
}
}
}
// free resource
return 0;
}
else if ((pEvent[i].events&EPOLLIN) && (pEvent[i].data.fd == listenFd))
{
acceptSeq++;
printf("fds: %d i: %d listenFd: %d fd: %d : acceptSeq: %d \n", fds, i, listenFd, pEvent[i].data.fd, acceptSeq);
accepttask(NULL);
}
if (pEvent[i].events&EPOLLOUT) // write event?
{
//ev->call_back(ev->fd, events[i].events, ev->arg);
//task_s* pt = new task_s;
//pt->fd = events[i].data.fd;
//pt->type = 2;
}
}
}
// free resource
return 0;
}