//////////////////////////////////////////////////////////////////////////////// /// 名 称:TCPSocket::Init /// 功 能:初始化对象 /// 参 数:void /// 返回 值:bool public //////////////////////////////////////////////////////////////////////////////// bool TCPSocket::Init() { // 读取配置文件 if (!LoadConfig()) { return false; } // 设置读写ID口文件最大数 SetLimitMax(); // 显示当前Socket配置情况 if (!ShowSocketStatus()) { return false; } // 初始化线程池 if (!ThreadPollInit()) { return false; } // 屏蔽多重发送的报错信号 if (!MaskSignal()) { return false; } // 创建Socket if (!CreateSocket()) { return false; } // 创建Epoll if (!CreateEpoll()) { return false; } // 绑定Socket if (!BindSocket()) { return false; } // 开启监听该Socket if (!ListenSocket()) { return false; } return true; }
int main() { struct epoll_event ev, events[MAX_EVENTS]; struct sockaddr_in client; struct sockaddr_in server; // const char* localhost = "127.0.0.1"; const char* localhost = "0.0.0.0"; int tcpfd, udpfd, nfds, confd; int servPort = 8888; socklen_t addrLen = sizeof(struct sockaddr); char line[MAX_LINE]; ssize_t n; MYSQL connection; pthread_t thread; pthread_attr_t attr; //create socket tcpfd = CreateSocket(TCP); //translate ip & port into sockaddr_in format Ip2SocketAddr(&server, localhost, servPort); //bind ip & port to socket BindSocketAddr(&server, tcpfd); //begin to listen listen(tcpfd, LISTEN_NUM); //create epoll epfd = CreateEpoll(MAX_EVENTS); //set fd nonblocking mode SetNonBlock(tcpfd); //register fd event to epoll EpollAdd(epfd, tcpfd, EPOLLIN|EPOLLET); //create thread pool InitPool(MAX_POOL_SIZE); //init a connection to MySql conn = mysql_init(NULL); if(mysql_real_connect(conn, "localhost", "root", "", "test_server", 0, NULL, 0) == NULL){ perror("no database connection...\n"); exit(1); } while(1){ if((nfds = EpollWait(epfd, events, 20, 500)) == -1){ perror("epoll_wait\n"); exit(-1); } for(int i = 0; i < nfds; i++) { if(events[i].data.fd == tcpfd) { confd = accept(tcpfd, (struct sockaddr *)&client, &addrLen); if(confd < 0) { perror("accept error \n"); exit(1); } else printf("connect %s:%d socket :%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port), confd); // SetNonBlock(confd); EpollAdd(epfd, confd, EPOLLIN|EPOLLET); if(IsRecvIn(&events[i])) AddTask2Pool(MessageHandlerThread, (void *)&confd); } }//for(0 to nfds) } }
/// 创建TCP服务器 BOOL CTcpEpollServer::Create(uint16_t nSvrPort, ITcpServerEvent* pSvrEvent, ENUM_ENCRYPT_TYPE enType) { // 参数检查 ASSERT(pSvrEvent); ASSERT(nSvrPort); if(NULL == pSvrEvent || 0 == nSvrPort) return FALSE; BOOL bResult = FALSE; m_pTcpEvent = pSvrEvent; SetEncryptType(enType); do { // 创建EPOLL uint32_t nProcessors = sysconf(_SC_NPROCESSORS_CONF); nProcessors = nProcessors == 0 ? 1 : nProcessors; uint32_t nThreadNumber = nProcessors * 2 + 2; m_hEpollHandle = CreateEpoll(MAX_SOCKET_CONNECT_NUMBER / 2); if(-1 == m_hEpollHandle) break; // 创建SOCKET m_hListenSocket = CreateSocket(nSvrPort); if(INVALID_SOCKET == m_hListenSocket) break; m_ListenContext.m_hSocket = m_hListenSocket; // SOCKET和EPOLL绑定 struct epoll_event ev; ev.events = EPOLLIN | EPOLLET; //读事件 ET模式 ev.data.ptr = (void*)&m_ListenContext; if (epoll_ctl(m_hEpollHandle, EPOLL_CTL_ADD, m_hListenSocket, &ev) < 0) { TraceLogError("CTcpEpollServer::Create 绑定Epoll失败 ERROR=%s!\n", strerror(errno)); break; } // 创建Epoll线程 if(!m_EpollWaitThread.StartThread(this, nThreadNumber)) break; // 创建检查线程 if(!m_CheckThread.StartThread(this)) break; bResult = TRUE; } while (FALSE); if(!bResult) { Destroy(); } return bResult; }
int IoWait::ChooseEpoll(uint32_t event) { CreateEpoll(); return (event & EPOLLIN) ? epoll_fds_[(int)EpollType::read] : epoll_fds_[(int)EpollType::write]; }
int IoWait::GetEpoll(int type) { CreateEpoll(); return epoll_fds_[type]; }