////////////////////////////////////////////////////////////////// // 投递Accept请求 bool CIOCPModel::_PostAccept( PER_IO_CONTEXT* pAcceptIoContext ) { //ASSERT( INVALID_SOCKET!=m_pListenContext->m_Socket ); // 准备参数 DWORD dwBytes = 0; pAcceptIoContext->m_OpType = ACCEPT_POSTED; WSABUF *p_wbuf = &pAcceptIoContext->m_wsaBuf; OVERLAPPED *p_ol = &pAcceptIoContext->m_Overlapped; // 为以后新连入的客户端先准备好Socket( 这个是与传统accept最大的区别 ) pAcceptIoContext->m_sockAccept = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if( INVALID_SOCKET==pAcceptIoContext->m_sockAccept ) { //_ShowMessage("创建用于Accept的Socket失败!错误代码: %d", WSAGetLastError()); return false; } // 投递AcceptEx if(FALSE == m_lpfnAcceptEx( m_pListenContext->m_Socket, pAcceptIoContext->m_sockAccept, p_wbuf->buf, 0/*p_wbuf->len - ((sizeof(SOCKADDR_IN)+16)*2)*/, sizeof(SOCKADDR_IN)+16, sizeof(SOCKADDR_IN)+16, &dwBytes, p_ol)) { if(WSA_IO_PENDING != WSAGetLastError()) { //_ShowMessage("投递 AcceptEx 请求失败,错误代码: %d", WSAGetLastError()); return false; } } return true; }
////////////////////////////////////////////////////////////////// // 投递Accept请求 bool IocpPool::_PostAccept( IoContent* pAcceptIoContext ) { //ASSERT( INVALID_SOCKET!=m_pListenContext->m_Socket ); // 准备参数 DWORD dwBytes = 0; pAcceptIoContext->optype = ACCEPT_POSTED; WSABUF *p_wbuf = &pAcceptIoContext->m_wsaBuf; OVERLAPPED *p_ol = &pAcceptIoContext->overlapped; // 为以后新连入的客户端先准备好Socket( 这个是与传统accept最大的区别 ) SOCKET socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if( INVALID_SOCKET == socket) { // _ShowMessage("创建用于Accept的Socket失败!错误代码: %d", WSAGetLastError()); return false; } pAcceptIoContext->sockfd = socket; // 投递AcceptEx if(FALSE == m_lpfnAcceptEx( m_pListenContext->getHandle().getHandle(), socket, p_wbuf->buf,0,// p_wbuf->len - ((sizeof(SOCKADDR_IN)+16)*2), sizeof(SOCKADDR_IN)+16, sizeof(SOCKADDR_IN)+16, &dwBytes, p_ol)) { char buffer[1024]={'\0'}; sprintf(buffer,"投递 AcceptEx 请求失败,错误代码: %d\n", WSAGetLastError()); if(WSA_IO_PENDING != WSAGetLastError()) { // _ShowMessage("投递 AcceptEx 请求失败,错误代码: %d", WSAGetLastError()); return false; } } return true; }
/// 添加AcceptEx队列 BOOL CTcpIocpServer::AddAcceptEx(OVERLAPPEDPLUS* pOverlap) { // 参数检查 ASSERT(pOverlap); if(NULL == pOverlap) return FALSE; // 创建Socket SOCKET hAcceptSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED); if (INVALID_SOCKET == hAcceptSocket) { TraceLogError("CTcpIocpServer::AddAcceptEx 创建SOCKET句柄失败 ERROR=%d\n", WSAGetLastError()); return FALSE; } // 自动继承m_hSocket的属性 setsockopt(hAcceptSocket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *)&m_hListenSocket, sizeof(m_hListenSocket)); // 申请OverlapPlus pOverlap->m_hSocket = hAcceptSocket; pOverlap->m_enIOType = IO_ACCEPT; { // 添加至队列 CCriticalAutoLock loAutoLock(m_AcceptExListLock); POSITION position = m_AcceptExList.AddTail(pOverlap); // 设置OverlapKey(必须,方便快速删除用) pOverlap->m_nOverlapKey = (uint64_t)position; } // 接受连接请求 DWORD dwBytes = 0; BOOL bIsSuccess = m_lpfnAcceptEx(m_hListenSocket, hAcceptSocket, pOverlap->m_szBuffer, pOverlap->m_wsaBuffer.len - ((sizeof(SOCKADDR_IN) + 16) * 2), sizeof(SOCKADDR_IN) + 16, sizeof(SOCKADDR_IN) + 16, &dwBytes, (LPWSAOVERLAPPED)pOverlap); uint32_t nLastError = WSAGetLastError(); if (!bIsSuccess && nLastError != ERROR_IO_PENDING) { closesocket(hAcceptSocket); hAcceptSocket = INVALID_SOCKET; TraceLogError("CTcpIocpServer::AddAcceptEx AcceptEx()调用失败 ERROR=%d\n", nLastError); return FALSE; } return TRUE; }
//----------------------------------- BOOL MightyTCPCompletionPortServer::PostAccept(PCompletionPort_BufObj pBuffer) { // 设置I/O类型 pBuffer->nOperation = OP_ACCEPT; // 投递此重叠I/O DWORD dwBytes; pBuffer->sAccept = ::WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); BOOL b = m_lpfnAcceptEx(pBuffer->pSocket->s, pBuffer->sAccept, pBuffer->buff, pBuffer->nLen - ((sizeof(sockaddr_in) + 16) * 2), sizeof(sockaddr_in) + 16, sizeof(sockaddr_in) + 16, &dwBytes, &pBuffer->wsaol); if(!b && ::WSAGetLastError() != WSA_IO_PENDING) { return FALSE; } return TRUE; }
BOOL CIOCPServer::PostAccept(CIOCPBuffer *pBuffer) // 在监听套节字上投递Accept请求 { // 设置I/O类型 pBuffer->nOperation = OP_ACCEPT; // 投递此重叠I/O DWORD dwBytes; pBuffer->sClient = ::WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); BOOL b = m_lpfnAcceptEx(m_sListen, pBuffer->sClient, pBuffer->buff, pBuffer->nLen - ((sizeof(sockaddr_in) + 16) * 2), sizeof(sockaddr_in) + 16, sizeof(sockaddr_in) + 16, &dwBytes, &pBuffer->ol); if(!b && ::WSAGetLastError() != WSA_IO_PENDING) { return FALSE; } return TRUE; };
if (!m_lpfnAcceptEx) return -1; if (!_new_socket) { int ret = _new_socket.open(); ON_ERROR_LOG_LAST_ERROR_AND_DO(ret, != , 0, return err); } DWORD nBytes = 0; memset(&_io_context->m_overlapped, 0, sizeof(OVERLAPPED)); _io_context->m_opt_type = SOCKET_ACCEPT; _io_context->m_socket = _new_socket; // call AcceptEx() int ret = m_lpfnAcceptEx( m_hSocket, (SOCKET)_new_socket, m_buffer, 0, 64, 64, &nBytes, (LPOVERLAPPED)_io_context); if (ret != 0 && LiangZhu::GetLastSysError(true) != ERROR_IO_PENDING) { ret = -1; } return ret; } int CSocketTcpEx::connectEx(CInetAddr& _server_address, PPER_IO_CONTEXT_t _io_context) { DWORD recv_bytes = 0, flags = 0; if (_io_context) {