void tcp_frame::run() { if (_Imp->bOpen) return; if (_Imp->errorCode) { NET_LOG.console("tcp_frame start failed:{0}", _Imp->errorCode.message().c_str()); return; } NET_LOG.console("tcp_frame start succeed"); _Imp->servicepool.run(); if (_Imp->bCheckTimeOut) { NET_LOG.console("tcp_frame start check timeout thread succeed"); _Imp->timeOutThread.set_interval(_Imp->timeoutCheckInterval); _Imp->timeOutThread.onUpdate = std::bind(&tcp_frame::checkTimeOut, this, std::placeholders::_1); _Imp->timeOutThread.run(); } postAccept(); _Imp->bOpen = true; }
void TCPServer::handleAccept( PSocketContext pSocketContext, PIOContext pIOContext) { setsockopt(pIOContext->fd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&pSocketContext->fd, sizeof(SOCKET)); sockaddr_in* clientAddr = nullptr; sockaddr_in* localAddr = nullptr; int clientLen = sizeof(sockaddr_in); int localLen = clientLen; _fnGetAcceptExSockAddrs( pIOContext->overlappedBuffer.buf, 0, sizeof(sockaddr_in) + 16, sizeof(sockaddr_in) + 16, (sockaddr**)&localAddr, &localLen, (sockaddr**)&clientAddr, &clientLen); auto clientPort = ntohs(clientAddr->sin_port); auto wClientIP = AnsiToUnicode(inet_ntoa(clientAddr->sin_addr)); LOG("创建新会话[%s-%d]", wClientIP.c_str(), clientPort); PSocketContext pClientSocketContext = new SocketContext(); pClientSocketContext->fd = pIOContext->fd; pClientSocketContext->clientIP = wClientIP; pClientSocketContext->clientPort = clientPort; if(!bind2IOCP(pClientSocketContext)){ delete pClientSocketContext; pClientSocketContext = nullptr; return; } // 立即投递接受数据请求 auto client = new TCPServerSession(this, pClientSocketContext); client->postRecv(nullptr); addClients(client); // 立即投递下一个accept请求 pIOContext->resetBuffer(); postAccept(pIOContext); }
void tcp_frame::postAccept() { if (!_Imp->acceptor.is_open()) { return; } auto& ser = _Imp->servicepool.get_service(); auto sock = std::make_shared<socket>(_hander,ser); sock->setmodule_id(_Imp->moduleid); _Imp->acceptor.async_accept(sock->get_socket(), [sock, this, &ser](const asio::error_code& e) { if (!e) { ser.add_socket(sock); postAccept(); return; } _Imp->errorCode = e; }); }
bool TCPServer::createListenerSocket(unsigned short port) { _listenSocketContext = new SocketContext(); _listenSocketContext->fd = WSASocket(AF_INET, SOCK_STREAM, 0, 0, 0, WSA_FLAG_OVERLAPPED); if(INVALID_SOCKET == _listenSocketContext->fd) { SYSLOG("初始化Socket失败", WSAGetLastError()); return false; } if(!bind2IOCP(_listenSocketContext)) { return false; } sockaddr_in netAddr; memset(&netAddr, 0, sizeof(sockaddr_in)); netAddr.sin_family = AF_INET; netAddr.sin_port = htons(port); netAddr.sin_addr.s_addr = htonl(INADDR_ANY); if(SOCKET_ERROR == bind(_listenSocketContext->fd, (sockaddr*)&netAddr, sizeof(netAddr))) { SYSLOG("bind()执行错误", WSAGetLastError()); return false; } if(SOCKET_ERROR == listen(_listenSocketContext->fd, 128)) { SYSLOG("listen()执行出现错误", WSAGetLastError()); return false; } GUID guidAcceptEx = WSAID_ACCEPTEX; GUID guidAcceptExSockAddrs = WSAID_GETACCEPTEXSOCKADDRS; unsigned long dwBytes = 0; if(SOCKET_ERROR == WSAIoctl( _listenSocketContext->fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &guidAcceptEx, sizeof(guidAcceptEx), &_fnAcceptEx, sizeof(_fnAcceptEx), &dwBytes, nullptr, nullptr)) { SYSLOG("获取AcceptEx函数指针失败", WSAGetLastError()); return false; } if(SOCKET_ERROR == WSAIoctl( _listenSocketContext->fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &guidAcceptExSockAddrs, sizeof(guidAcceptExSockAddrs), &_fnGetAcceptExSockAddrs, sizeof(_fnGetAcceptExSockAddrs), &dwBytes, nullptr, nullptr)) { SYSLOG("获取GetAcceptExSockAddrs函数指针失败", WSAGetLastError()); return false; } for(int i = 0; i < s_maxPostAccept; i++) { auto pIOContext = _listenSocketContext->getNewIOContext(); if(!postAccept(pIOContext)) { _listenSocketContext->removeIOContext(pIOContext); } } unsigned id = 0; _pThreads = new HANDLE[_threads]; for(int i = 0; i < _threads; i++) { _pThreads[i] = (HANDLE)_beginthreadex(nullptr, 0, &workerLoop, (void*)this, 0, &id); } LOG("IOCP初始化成功,建立[%d]个消息处理工作者", _threads); return true; }