stoneage8.5/石器时代服务器端最新完整源代码/Serv/gmsv/epollnet.c
2020-06-22 17:49:02 +08:00

262 lines
5.3 KiB
C

/*
* epollnet.c
*
* Created on: 2015年10月22日
* Author: hult
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <errno.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <string.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include "net.h"
#include "epollnet.h"
#include "configfile.h"
#include "version.h"
#ifdef _EPOLL_ET_MODE
struct epoll_event *events = NULL;
int epollFd = -1;
int epoll_init();
int epoll_socket(int domain, int type, int protocol);
int epoll_cleanup();
//绑定监听端口
int epoll_bind(int port) {
struct sockaddr_in listenAddr;
int sfd = -1;
if (-1 == epoll_init()) {
printf("epoll_init err\n");
return -1;
}
if ((sfd = epoll_socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("epoll_socket err\n");
epoll_cleanup();
return -1;
}
listenAddr.sin_family = AF_INET;
listenAddr.sin_port = htons(port);
listenAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (-1 == bind(sfd, (struct sockaddr*) &listenAddr, sizeof(listenAddr))) {
printf("bind err %d\n", errno);
epoll_cleanup();
return -1;
}
if (-1 == listen(sfd, 1024)) {
printf("listen err\n");
epoll_cleanup();
return -1;
}
//Add bindedfd into epoll
if (-1 == epoll_new_conn(sfd)) {
printf("eph_new_conn err\n");
close(sfd);
epoll_cleanup();
return -1;
}
return sfd;
}
int epoll_init() {
if (!(events = (struct epoll_event*) malloc(
ConnectLen * sizeof(struct epoll_event)))) {
return -1;
}
if ((epollFd = epoll_create(ConnectLen)) < 0) {
return -1;
}
return 0;
}
int epoll_socket(int domain, int type, int protocol) {
int sockFd = -1;
if ((sockFd = socket(domain, type, protocol)) < 0) {
return -1;
}
//端口复用
if (getReuseaddr()) {
int sendbuff;
setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, (char *) &sendbuff,
sizeof(sendbuff));
}
//非阻塞
if (epoll_set_nonblock(sockFd) < 0) {
return -1;
}
return sockFd;
}
int epoll_set_nonblock(int fd) {
int flag = -1;
//Set Socket to non-block
if ((flag = fcntl(fd, F_GETFL, 0)) < 0
|| fcntl(fd, F_SETFL, flag | O_NONBLOCK) < 0) {
close(fd);
return -1;
}
return 0;
}
int epoll_new_conn(int sfd) {
struct epoll_event epollEvent;
memset(&epollEvent, 0, sizeof(struct epoll_event));
epollEvent.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLET;
epollEvent.data.fd = sfd;
if (epoll_ctl(epollFd, EPOLL_CTL_ADD, sfd, &epollEvent) < 0) {
return -1;
}
return 0;
}
int epoll_close_conn(int sfd) {
struct epoll_event epollEvent;
memset(&epollEvent, 0, sizeof(struct epoll_event));
epollEvent.events = NULL;
epollEvent.data.fd = sfd;
if (epoll_ctl(epollFd, EPOLL_CTL_DEL, sfd, &epollEvent) < 0) {
return -1;
}
return 0;
}
int epoll_mod_read(int sfd) {
struct epoll_event epollEvent;
memset(&epollEvent, 0, sizeof(struct epoll_event));
epollEvent.events = EPOLLIN | EPOLLHUP | EPOLLERR;
epollEvent.data.fd = sfd;
if (epoll_ctl(epollFd, EPOLL_CTL_MOD, sfd, &epollEvent) < 0) {
return -1;
}
return 0;
}
int epoll_mod_write(int sfd) {
struct epoll_event epollEvent;
memset(&epollEvent, 0, sizeof(struct epoll_event));
epollEvent.events = EPOLLOUT | EPOLLHUP | EPOLLERR;
epollEvent.data.fd = sfd;
if (epoll_ctl(epollFd, EPOLL_CTL_MOD, sfd, &epollEvent) < 0) {
return -1;
}
return 0;
}
int epoll_cleanup() {
free(events);
close(epollFd);
return 0;
}
//将acfd添加到epoll中
int epoll_add_acfd(int acfd) {
if (epoll_set_nonblock(acfd) == -1) {
return -1;
}
if (epoll_new_conn(acfd) == -1) {
return -1;
}
return 0;
}
//读封包处理
void PacketWrap_Thread(int state) {
pthread_detach(pthread_self());
printf("Thread %d Start\n", state);
while (1) {
int i;
for (i = state; i < ConnectLen; i += _EPOLL_POOL_COUNT) {
Dispatch_read_buffer(i, state);
usleep(1);
}
}
}
//启动封包处理线程
int Start_PacketWrapper() {
int i, ret;
pthread_t thread;
for (i = 0; i < _EPOLL_POOL_COUNT; i++) {
ret = pthread_create(&thread, NULL, PacketWrap_Thread, (void *) i);
if (ret != 0) {
return ret;
}
}
return 0;
}
//主循环
void EpollLoop_Thread() {
pthread_detach(pthread_self());
//LOOP
while (1) {
int n, i;
n = epoll_wait(epollFd, events, ConnectLen, -1);
for (i = 0; i < n; i++) {
if ((events[i].events & EPOLLERR)
|| (events[i].events & EPOLLHUP)) {
CONNECT_endOne_debug(events[i].data.fd);
continue;
} else if (events[i].data.fd == bindedfd) {
while (1) {
if (doSocketAccept() == -1) {
break;
}
}
} else if (events[i].events & EPOLLIN) {
//接收
doSocketRecv(events[i]);
} else if (events[i].events & EPOLLOUT) {
//发送
doSocketSend(events[i]);
}
}
usleep(1);
}
epoll_cleanup();
}
//启动epoll主循环线程
int Start_Epoll_Loop() {
pthread_t thread;
int ret = pthread_create(&thread, NULL, EpollLoop_Thread, NULL);
return ret;
}
//void EpollSendLoop_Thread() {
// pthread_detach(pthread_self());
// while (1) {
// doSocketSend();
// }
//}
//
////启动epoll发送线程
//int Start_Epoll_SendLoop() {
// pthread_t thread;
// int ret = pthread_create(&thread, NULL, EpollSendLoop_Thread, NULL);
// return ret;
//}
#endif