关于WSAWaitForMultipleEvents的奇怪问题

udknight 2009-06-11 01:57:50
近来想学学网络编程,就修改了网络流传的一个IOCP封装类编写了一个服务器框架。奇怪的是无法接受客户端的连接请求。我一步一步排查。发现出错地址在这:
unsigned __stdcall NetCompletionPort::AcceptThreadFun(LPVOID param)
{
OutputDebugString("NetCompletionPort::AcceptThreadFun(LPVOID param)");
NetCompletionPort* p = (NetCompletionPort*)param;

DWORD dwRet = 0;
while(p->m_isCreate)
{
OutputDebugString("进行AcceptThreadFun 循环");
if (!p->m_isCreate)
break;
OutputDebugString("before WSAWaitForMultipleEvents");
dwRet = ::WSAWaitForMultipleEvents(1,
&(p->m_hEventListen),
FALSE,
100,
FALSE);

if (WSA_WAIT_TIMEOUT == dwRet)
{
OutputDebugString("WSAWaitForMultipleEvents WSA_WAIT_TIMEOUT");
continue;
}


WSANETWORKEVENTS WSAEvents;
dwRet = WSAEnumNetworkEvents(p->m_listenSocket, p->m_hEventListen,
&WSAEvents);

if (SOCKET_ERROR == dwRet)
break;


if ((WSAEvents.lNetworkEvents & FD_ACCEPT) && (0 == WSAEvents.iErrorCode[FD_ACCEPT_BIT]))
{
OutputDebugString("PostAcceptEx");
if(!p->PostAcceptEx())
return FALSE;
else
return TRUE;
}

}
return TRUE;
}

当客户端发出连接请求后,WSAWaitForMultipleEvents还是会返回WSA_WAIT_TIMEOUT ,而不会执行到下面的PostAcceptEx()函数。
...全文
167 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
udknight 2009-06-11
  • 打赏
  • 举报
回复
汗,一直以为是IOCP那有问题,原来是m_iocp.StartServer(m_ServPort); 前面没有UpdateData();
udknight 2009-06-11
  • 打赏
  • 举报
回复
C:\Documents and Settings\udknight>telnet 127.0.0.1 8000
正在连接到127.0.0.1...不能打开到主机的连接, 在端口 8000: 连接失败

udknight 2009-06-11
  • 打赏
  • 举报
回复
我用SocketTool测试的。连接不上去。
Conry 2009-06-11
  • 打赏
  • 举报
回复
我这里测试没有问题
是不是客户端的问题
你可以用命令行的telnet试一下

telnet 127.0.0.1 你的端口
udknight 2009-06-11
  • 打赏
  • 举报
回复
代码贴的这么详细了。怎么没有人说句话呢?
udknight 2009-06-11
  • 打赏
  • 举报
回复
up
IGAWhoyo 2009-06-11
  • 打赏
  • 举报
回复
UP
IGAWhoyo 2009-06-11
  • 打赏
  • 举报
回复
我简单的调用了下

NetCompletionPort m_iocp;
m_iocp.StartServer(m_ServPort);

IGAWhoyo 2009-06-11
  • 打赏
  • 举报
回复
NetCompletionPort.cpp 代码 下

bool NetCompletionPort::PostAcceptEx()
{
OutputDebugString("NetCompletionPort::PostAcceptEx()");
SOCKET socketAcp = WSASocket(PF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,0,WSA_FLAG_OVERLAPPED);
if(INVALID_SOCKET == socketAcp)
return FALSE;
LPPER_IO_CONTEXT temp = GetIoMem();
temp->IoOperation = IO_ACCEPT;
temp->sClient = socketAcp;
temp->id = socketAcp;
temp->wsabuf.len = MAX_BUF;
DWORD dwByte;
if(!m_pAcceptEx(m_listenSocket,socketAcp,temp->buf,MAX_BUF-((sizeof(SOCKADDR_IN)+16)*2),
sizeof(SOCKADDR_IN)+16,sizeof(SOCKADDR_IN)+16,&dwByte,&temp->ol))
{
if(ERROR_IO_PENDING != WSAGetLastError())
{
::closesocket(socketAcp);
InsertIoMem(temp);
return FALSE;
}
}
return TRUE;
}

bool NetCompletionPort::Disconnect(int socket)
{
OutputDebugString("NetCompletionPort::Disconnect(int socket)");
bool rlt = FALSE;
EnterCriticalSection(&m_clientListSection);
std::map<int,NetClient*>::iterator pos = m_pClientList->find(socket);
if(pos != m_pClientList->end())
{
NetClient* pClient = pos->second;
pClient->Disconnect();
InsertHandleMem(pClient->m_pComKey);
delete pClient;
m_pClientList->erase(socket);
rlt = TRUE;
}
LeaveCriticalSection(&m_clientListSection);
return rlt;
}

void NetCompletionPort::SendPacket(int socket,void * pData,bool encrypt)
{
OutputDebugString("NetCompletionPort::SendPacket(int socket,void * pData,bool encrypt)");
DWORD SendBytes,Flags;
Flags = 0;
int length = 0;
EncryptPacket(pData,length,IO_SEND,encrypt);
if(length > MAX_BUF)
return;
LPPER_IO_CONTEXT pIoMem = GetIoMem();
pIoMem->IoOperation = IO_WRITE;
pIoMem->sClient = socket;
pIoMem->id = socket;
memset(pIoMem->buf,0,MAX_BUF);
pIoMem->wsabuf.buf = pIoMem->buf;
pIoMem->wsabuf.len = MAX_BUF;
memset(&(pIoMem->ol),0,sizeof(WSAOVERLAPPED));
memcpy(pIoMem->buf,pData,length);
WSASend(socket,&pIoMem->wsabuf,1,&SendBytes,Flags,&(pIoMem->ol),NULL);
EncryptPacket(pData,length,IO_SEND,encrypt);
}

void NetCompletionPort::EncryptPacket(void * pData,int & length,BYTE type,bool encrypt)
{
}

void NetCompletionPort::RecvData(void * pData,NetClient* pClient)
{
}

void NetCompletionPort::AcceptEvent(LPPER_IO_CONTEXT pIo,LPPER_HANDLE_CONTEXT pHd,DWORD dwByte)
{
OutputDebugString("NetCompletionPort::AcceptEvent(LPPER_IO_CONTEXT pIo,LPPER_HANDLE_CONTEXT pHd,DWORD dwByte)");
DWORD flag = 0;
DWORD dwRecv = 0;
DWORD ret = 0;
NetClient* pClient = new NetClient(pHd->IoSocket);
pClient->m_pComKey = pHd;
AddClient(pClient);
int count = 0;
while(count < (RECV_COUNT - 1))
{
LPPER_IO_CONTEXT p = GetIoMem();
memset(p,0,sizeof(PER_IO_CONTEXT));
p->sClient = pIo->sClient;
p->id = pIo->id;
p->wsabuf.buf = p->buf;
p->wsabuf.len = MAX_BUF;
p->IoOperation = IO_READ;
ret = WSARecv(pHd->IoSocket,&(p->wsabuf),1,&dwRecv,&flag,&(p->ol),NULL);
if(SOCKET_ERROR == ret)
{
if(WSA_IO_PENDING != WSAGetLastError())
{
Disconnect(pHd->IoSocket);
InsertIoMem(pIo);
return;
}
}
count++;
}
if(dwByte > 0)
{
SOCKADDR * lpLocalSockaddr = NULL,* lpRemoteSockaddr = NULL;
int LocalSockAddrLen = 0,RemoteSockaddrLen = 0;
m_pGetAcceptExSockaddrs(pIo->buf,pIo->wsabuf.len - ((sizeof(SOCKADDR_IN) + 16)*2),
sizeof(SOCKADDR_IN) + 16,sizeof(SOCKADDR_IN) + 16,&lpLocalSockaddr,&LocalSockAddrLen,
&lpRemoteSockaddr,&RemoteSockaddrLen);
if(lpRemoteSockaddr != NULL)
memcpy(&pClient->m_address,lpRemoteSockaddr,sizeof(SOCKADDR_IN));
RecvData(pIo->buf,pClient);
}
memset(pIo->buf,0,MAX_BUF);
memset(&(pIo->ol),0,sizeof(WSAOVERLAPPED));
pIo->wsabuf.buf = pIo->buf;
pIo->wsabuf.len = MAX_BUF;
pIo->IoOperation = IO_READ;
ret = WSARecv(pHd->IoSocket,&(pIo->wsabuf),1,&dwRecv,&flag,&(pIo->ol),NULL);
if(SOCKET_ERROR == ret)
{
if(WSA_IO_PENDING != WSAGetLastError())
{
Disconnect(pHd->IoSocket);
InsertIoMem(pIo);
return;
}
}
}

void NetCompletionPort::SendEvent(LPPER_IO_CONTEXT pIo,LPPER_HANDLE_CONTEXT pHd,DWORD dwByte)
{
OutputDebugString("NetCompletionPort::SendEvent(LPPER_IO_CONTEXT pIo,LPPER_HANDLE_CONTEXT pHd,DWORD dwByte)");
if(dwByte < 0)
{
InsertIoMem(pIo);
Disconnect(pHd->IoSocket);
}
else
InsertIoMem(pIo);
}

void NetCompletionPort::RecvEvent(LPPER_IO_CONTEXT pIo,LPPER_HANDLE_CONTEXT pHd,DWORD dwByte)
{
OutputDebugString("NetCompletionPort::RecvEvent(LPPER_IO_CONTEXT pIo,LPPER_HANDLE_CONTEXT pHd,DWORD dwByte)");
if(dwByte < 0)
{
InsertIoMem(pIo);
Disconnect(pHd->IoSocket);
}
else
{
RecvData(pIo->buf,GetClient(pHd->IoSocket));
DWORD flag = 0;
DWORD dwRecv = 0;
DWORD ret = 0;
memset(pIo->buf,0,MAX_BUF);
memset(&(pIo->ol),0,sizeof(WSAOVERLAPPED));
pIo->wsabuf.buf = pIo->buf;
pIo->wsabuf.len = MAX_BUF;
pIo->IoOperation = IO_READ;
ret = WSARecv(pHd->IoSocket,&(pIo->wsabuf),1,&dwRecv,&flag,&(pIo->ol),NULL);
if(SOCKET_ERROR == ret)
{
if(WSA_IO_PENDING != WSAGetLastError())
{
Disconnect(pHd->IoSocket);
InsertIoMem(pIo);
return;
}
}
}
}

void NetCompletionPort::CloseEvent(LPPER_IO_CONTEXT pIo,LPPER_HANDLE_CONTEXT pHd)
{
OutputDebugString("NetCompletionPort::CloseEvent(LPPER_IO_CONTEXT pIo,LPPER_HANDLE_CONTEXT pHd)");
Disconnect(pIo->sClient);
InsertIoMem(pIo);
}

unsigned __stdcall NetCompletionPort::WorkThreadFun(LPVOID param)
{
OutputDebugString("NetCompletionPort::WorkThreadFun(LPVOID param)");
DWORD dwByteSend = 0;
DWORD dwByteRecv = 0;
DWORD dwByteTrans = 0;
bool flag = FALSE;
BOOL bRet = FALSE;
BYTE opType = 0;

NetCompletionPort* p = (NetCompletionPort*)param;
HANDLE hComPort = p->m_comPort;
LPPER_IO_CONTEXT pIoData = NULL;
LPPER_HANDLE_CONTEXT pHandleData = NULL;

while(p->m_isCreate)
{
pIoData = NULL;
pHandleData = NULL;
bRet = GetQueuedCompletionStatus(hComPort,
&dwByteTrans,
(LPDWORD)&pHandleData,
(LPOVERLAPPED*)&pIoData,
INFINITE);
if(FALSE == bRet)
continue;

else if(pIoData == NULL)
return FALSE;

opType = pIoData->IoOperation;
if(opType != IO_ACCEPT && dwByteTrans == 0)
{
p->Disconnect(pHandleData->IoSocket);
p->InsertIoMem(pIoData);
continue;
}
if(opType == IO_ACCEPT)
{
//释放节点
p->ReleaseConnect((DWORD)pIoData->sClient);
if(SOCKET_ERROR == setsockopt(p->m_listenSocket,SOL_SOCKET,SO_UPDATE_ACCEPT_CONTEXT,
(char*)&(pIoData->sClient),sizeof(pIoData->sClient)))
{
::closesocket(pIoData->sClient);
p->InsertIoMem(pIoData);
continue;
}
else
{
//分配单句柄数据
LPPER_HANDLE_CONTEXT pNeW = p->GetHandleMem();
pNeW->IoSocket = pIoData->sClient;
if(!CreateIoCompletionPort((HANDLE)pIoData->sClient,p->m_comPort,(DWORD)pNeW,0))
{
::closesocket(pIoData->sClient);
p->InsertIoMem(pIoData);
p->InsertHandleMem(pNeW);
continue;
}
p->AcceptEvent(pIoData,pNeW,dwByteTrans);
}
continue;
}
else if(opType == IO_READ)
{
p->RecvEvent(pIoData,pHandleData,dwByteTrans);
continue;
}
else if(opType == IO_WRITE)
{
p->SendEvent(pIoData,pHandleData,dwByteTrans);
continue;
}
else
{
p->Disconnect(pHandleData->IoSocket);
p->InsertIoMem(pIoData);
continue;
}
}
return 1;
}

unsigned __stdcall NetCompletionPort::AcceptThreadFun(LPVOID param)
{
OutputDebugString("NetCompletionPort::AcceptThreadFun(LPVOID param)");
NetCompletionPort* p = (NetCompletionPort*)param;

DWORD dwRet = 0;
while(p->m_isCreate)
{
OutputDebugString("进行AcceptThreadFun 循环");
if (!p->m_isCreate)
break;
OutputDebugString("before WSAWaitForMultipleEvents");
dwRet = ::WSAWaitForMultipleEvents(1,
&(p->m_hEventListen),
FALSE,
100,
FALSE);

if (WSA_WAIT_TIMEOUT == dwRet)
{
OutputDebugString("WSAWaitForMultipleEvents WSA_WAIT_TIMEOUT");
continue;
}


OutputDebugString("after WSAWaitForMultipleEvents");
WSANETWORKEVENTS WSAEvents;
dwRet = WSAEnumNetworkEvents(p->m_listenSocket, //自动重置事件
p->m_hEventListen,
&WSAEvents);
OutputDebugString("after WSAEnumNetworkEvents");
if (SOCKET_ERROR == dwRet)
break;

OutputDebugString("Before PostAcceptEx");
if ((WSAEvents.lNetworkEvents & FD_ACCEPT) && (0 == WSAEvents.iErrorCode[FD_ACCEPT_BIT]))
{
OutputDebugString("PostAcceptEx");
if(!p->PostAcceptEx())
return FALSE;
else
return TRUE;
}

}
return TRUE;
}
udknight 2009-06-11
  • 打赏
  • 举报
回复
NetCompletionPort.cpp 代码 中

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////NetCompletionPort

NetCompletionPort::NetCompletionPort()
{
OutputDebugString("NetCompletionPort::NetCompletionPort()");
g_pHostServer = this;
m_pAcceptEx = NULL;
m_comPort = NULL;
m_port = 0;
m_listenSocket = NULL;
m_hEventListen = NULL;
m_isCreate = FALSE;

m_pWorkThreadList = new std::vector<WorkThread*>;
m_pThreadAccept = NULL;
m_pClientList = new std::map<int,NetClient*>;
m_pConnectList = new std::set<LPPER_IO_CONTEXT>;
m_pIoMemList = new std::deque<LPPER_IO_CONTEXT>;
m_pHandleMemList = new std::deque<LPPER_HANDLE_CONTEXT>;

m_pClientList->clear();
m_pConnectList->clear();
m_pIoMemList->clear();
m_pHandleMemList->clear();

InitializeCriticalSection(&m_clientListSection);
InitializeCriticalSection(&m_conSection);
InitializeCriticalSection(&m_ioMenListSection);
InitializeCriticalSection(&m_hdMemListSection);
}

NetCompletionPort::~NetCompletionPort()
{
OutputDebugString("NetCompletionPort::~NetCompletionPort()");
// NetCompletionPort::StopServer();
delete m_pClientList;
delete m_pConnectList;
delete m_pIoMemList;
delete m_pHandleMemList;

DeleteCriticalSection(&m_clientListSection);
DeleteCriticalSection(&m_conSection);
DeleteCriticalSection(&m_ioMenListSection);
DeleteCriticalSection(&m_hdMemListSection);
}

bool NetCompletionPort::StartServer(int port)
{
OutputDebugString("NetCompletionPort::StartServer()");
WSADATA m_wsaData;
m_port = port;
if(WSAStartup(MAKEWORD(2,2), &m_wsaData))
return FALSE;
if(InitWinSock() && InitListenSocket() && InitListenEvent() && InitWorkThread())
{
m_isCreate = TRUE;

//将挂起的工作线程和接受线程都启动
m_pThreadAccept->Start();
std::vector<WorkThread*>::iterator pos = m_pWorkThreadList->begin();
while (pos != m_pWorkThreadList->end())
{
(*pos)->Start();
pos++;
}
}
else
{
StopServer();
return FALSE;
}
return TRUE;
}

bool NetCompletionPort::InitWinSock()
{
OutputDebugString("NetCompletionPort::InitWinSock()");
m_comPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
if(!m_comPort)
return FALSE;
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
for(int i=0;i<(sysInfo.dwNumberOfProcessors*2+2);i++)
{
WorkThread* pThread = new WorkThread(&WorkThreadFun,this);
if(pThread->Init())
m_pWorkThreadList->push_back(pThread);
else
{
delete pThread;
return FALSE;
}
}
return TRUE;
}

bool NetCompletionPort::InitListenSocket()
{
OutputDebugString("NetCompletionPort::InitListenSocket()");
m_listenSocket = WSASocket(AF_INET,
SOCK_STREAM,
0,
NULL,
0,
WSA_FLAG_OVERLAPPED);

if(INVALID_SOCKET == m_listenSocket)
{
m_listenSocket = NULL;
return FALSE;
}
if(!CreateIoCompletionPort((HANDLE)m_listenSocket,m_comPort,0,0))
return FALSE;

SOCKADDR_IN SockAddr;
ZeroMemory((char*)&SockAddr,sizeof(SOCKADDR_IN));
SockAddr.sin_family = AF_INET;
SockAddr.sin_port = htons(m_port);
SockAddr.sin_addr.s_addr = INADDR_ANY;
if(SOCKET_ERROR == bind(m_listenSocket,(PSOCKADDR)&SockAddr,sizeof(SockAddr)))
return FALSE;
if(SOCKET_ERROR == listen(m_listenSocket,SOMAXCONN))
return FALSE;

DWORD dwTemp=0;
if(SOCKET_ERROR == WSAIoctl(m_listenSocket,SIO_GET_EXTENSION_FUNCTION_POINTER,
&g_GUIDAcceptEx,sizeof(g_GUIDAcceptEx),&m_pAcceptEx,sizeof(m_pAcceptEx),
&dwTemp,NULL,NULL))
{
m_pAcceptEx = NULL;
return FALSE;
}
if(SOCKET_ERROR == WSAIoctl(m_listenSocket,SIO_GET_EXTENSION_FUNCTION_POINTER,
&g_GUIDGetAcceptExSockaddrs,sizeof(g_GUIDGetAcceptExSockaddrs),&m_pGetAcceptExSockaddrs,sizeof(m_pGetAcceptExSockaddrs),
&dwTemp,NULL,NULL))
{
m_pGetAcceptExSockaddrs = NULL;
return FALSE;
}

return TRUE;
}

bool NetCompletionPort::InitListenEvent()
{
OutputDebugString("NetCompletionPort::InitListenEvent()");
m_hEventListen = WSACreateEvent();
if(WSA_INVALID_EVENT == m_hEventListen)
return FALSE;
if(SOCKET_ERROR == WSAEventSelect(m_listenSocket,m_hEventListen,FD_ACCEPT))
return FALSE;
return TRUE;
}

bool NetCompletionPort::InitWorkThread()
{
OutputDebugString("NetCompletionPort::InitWorkThread()");
m_pThreadAccept = new WorkThread(AcceptThreadFun,this);
if(!m_pThreadAccept->Init())
{
delete m_pThreadAccept;
return FALSE;
}
return TRUE;
}

void NetCompletionPort::StopServer()
{
OutputDebugString("NetCompletionPort::StopServer()");
m_isCreate = FALSE;
if(m_comPort)
{
PostQueuedCompletionStatus(m_comPort,0,0,NULL);
CloseHandle(m_comPort);
m_comPort = NULL;
}
if(m_pThreadAccept != NULL)
{
m_pThreadAccept->Stop();
delete m_pThreadAccept;
m_pThreadAccept = NULL;
}
std::vector<WorkThread*>::iterator pos = m_pWorkThreadList->begin();
while (pos != m_pWorkThreadList->end())
{
(*pos)->Stop();
delete (*pos);
pos++;
}
m_pWorkThreadList->clear();
if(m_listenSocket != NULL)
{
closesocket(m_listenSocket);
m_listenSocket = NULL;
}
if(m_hEventListen != NULL)
{
CloseHandle(m_hEventListen);
m_hEventListen = NULL;
}
std::map<int,NetClient*>::iterator pos1 = m_pClientList->begin();
while(pos1 != m_pClientList->end())
{
NetClient* pClient = pos1->second;
pClient->Disconnect();
InsertHandleMem(pClient->m_pComKey);
delete pClient;
pos1++;
}
m_pClientList->clear();
std::set<LPPER_IO_CONTEXT>::iterator pos2 = m_pConnectList->begin();
while(pos2 != m_pConnectList->end())
{
free(*pos);
pos2++;
}
m_pConnectList->clear();
std::deque<LPPER_IO_CONTEXT>::iterator pos3 = m_pIoMemList->begin();
while(pos3 != m_pIoMemList->end())
{
free(*pos3);
pos3++;
}
m_pIoMemList->clear();
std::deque<LPPER_HANDLE_CONTEXT>::iterator pos4 = m_pHandleMemList->begin();
while(pos4 != m_pHandleMemList->end())
{
free(*pos4);
pos4++;
}
m_pHandleMemList->clear();
WSACleanup();
}

void NetCompletionPort::DeleteClient(NetClient* pClient)
{
OutputDebugString("NetCompletionPort::DeleteClient(NetClient* pClient)");
if(pClient == NULL)
return;
EnterCriticalSection(&m_clientListSection);
std::map<int,NetClient*>::iterator pos = m_pClientList->find(pClient->m_socket);
if(pos != m_pClientList->end())
{
NetClient* pClient = pos->second;
pClient->Disconnect();
InsertHandleMem(pClient->m_pComKey);
delete pClient;
m_pClientList->erase(pClient->m_socket);
}
LeaveCriticalSection(&m_clientListSection);
}

void NetCompletionPort::AddClient(NetClient* pClient)
{
OutputDebugString("NetCompletionPort::AddClient(NetClient* pClient)");
if(pClient == NULL)
return;
EnterCriticalSection(&m_clientListSection);
m_pClientList->insert(std::make_pair(pClient->m_socket,pClient));
LeaveCriticalSection(&m_clientListSection);
}

NetClient* NetCompletionPort::GetClient(int socket)
{
OutputDebugString("NetCompletionPort::GetClient(int socket)");
NetClient* pClient = NULL;
EnterCriticalSection(&m_clientListSection);
std::map<int,NetClient*>::iterator pos = m_pClientList->find(socket);
if(pos != m_pClientList->end())
pClient = pos->second;
LeaveCriticalSection(&m_clientListSection);
return pClient;
}

void NetCompletionPort::InsertConnect(LPPER_IO_CONTEXT pConnect)
{
OutputDebugString("NetCompletionPort::InsertConnect(LPPER_IO_CONTEXT pConnect)");
if(pConnect != NULL)
{
EnterCriticalSection(&m_conSection);
m_pConnectList->insert(pConnect);
LeaveCriticalSection(&m_conSection);
}
}

void NetCompletionPort::ReleaseConnect(int socket)
{
OutputDebugString("NetCompletionPort::ReleaseConnect(int socket)");
EnterCriticalSection(&m_conSection);
std::set<LPPER_IO_CONTEXT>::iterator pos = m_pConnectList->begin();
while (pos != m_pConnectList->end())
{
if((*pos)->sClient == socket)
{
m_pConnectList->erase(pos);
break;
}
pos++;
}
LeaveCriticalSection(&m_conSection);
}

LPPER_IO_CONTEXT NetCompletionPort::GetIoMem()
{
OutputDebugString("NetCompletionPort::GetIoMem()");
LPPER_IO_CONTEXT pData = NULL;
EnterCriticalSection(&m_ioMenListSection);
if(m_pIoMemList->size() > 0)
{
pData = m_pIoMemList->front();
m_pIoMemList->pop_front();
}
else
{
pData = (LPPER_IO_CONTEXT)malloc(sizeof(PER_IO_CONTEXT));
}
LeaveCriticalSection(&m_ioMenListSection);
memset(pData,0,sizeof(PER_IO_CONTEXT));
return pData;
}

LPPER_HANDLE_CONTEXT NetCompletionPort::GetHandleMem()
{
OutputDebugString("NetCompletionPort::GetHandleMem()");
LPPER_HANDLE_CONTEXT pData = NULL;
EnterCriticalSection(&m_hdMemListSection);
if(m_pHandleMemList->size() > 0)
{
pData = m_pHandleMemList->front();
m_pHandleMemList->pop_front();
}
else
{
pData = (LPPER_HANDLE_CONTEXT)malloc(sizeof(PER_HANDLE_CONTEXT));
}
LeaveCriticalSection(&m_hdMemListSection);
memset(pData,0,sizeof(PER_HANDLE_CONTEXT));
return pData;
}

void NetCompletionPort::InsertIoMem(LPPER_IO_CONTEXT pMem)
{
OutputDebugString("NetCompletionPort::InsertIoMem(LPPER_IO_CONTEXT pMem)");
EnterCriticalSection(&m_ioMenListSection);
if(m_pIoMemList->size() < MAX_MEM_COUNT)
m_pIoMemList->push_back(pMem);
else
free(pMem);
LeaveCriticalSection(&m_ioMenListSection);
}

void NetCompletionPort::InsertHandleMem(LPPER_HANDLE_CONTEXT pMem)
{
OutputDebugString("NetCompletionPort::InsertHandleMem(LPPER_HANDLE_CONTEXT pMem)");
EnterCriticalSection(&m_hdMemListSection);
if(m_pHandleMemList->size() < MAX_MEM_COUNT)
m_pHandleMemList->push_back(pMem);
else
free(pMem);
LeaveCriticalSection(&m_hdMemListSection);
}

udknight 2009-06-11
  • 打赏
  • 举报
回复
NetCompletionPort.cpp 代码 上

#include "stdafx.h"
#include "NetCompletionPort.h"
#include <ws2tcpip.h>

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////WorkThrerd

NetCompletionPort* g_pHostServer = NULL;

WorkThread::WorkThread()
{
OutputDebugString("WorkThread::WorkThread()");
m_hThread = NULL;
m_nThreadID = 0;
pnThreadFun = NULL;
m_pParam = NULL;
}

WorkThread::WorkThread(unsigned int (__stdcall*pnThreadFun)(LPVOID param),void* param)
{
OutputDebugString("WorkThread::WorkThread(unsigned int (__stdcall*pnThreadFun)(LPVOID param),void* param)");
m_hThread = NULL;
m_nThreadID = 0;
this->pnThreadFun = pnThreadFun;
m_pParam = param;
}

WorkThread::~WorkThread()
{
}

bool WorkThread::Init()
{
OutputDebugString("WorkThread::Init()");
m_hThread = (HANDLE)_beginthreadex(NULL,0,pnThreadFun,m_pParam,CREATE_SUSPENDED,&m_nThreadID);//CREATE_SUSPENDED
if(m_hThread)
return TRUE;
return FALSE;
}

void WorkThread::Start()
{
OutputDebugString("WorkThread::Start()");
if(m_hThread)
ResumeThread(m_hThread);
}

void WorkThread::Stop()
{
OutputDebugString("WorkThread::Stop()");
if (m_hThread)
{
DWORD code;
int count = 0;
while(TRUE)
{
if(count++ >= 5)
{
TerminateThread(m_hThread,0);
break;
}
GetExitCodeThread(m_hThread,&code);
if(code == STILL_ACTIVE)
{
Sleep(1000);
continue;
}
else
break;
}
CloseHandle(m_hThread);
m_hThread = NULL;
}
}

void WorkThread::SendMessage(UINT Msg, WPARAM wParam, LPARAM lParam)
{
OutputDebugString("WorkThread::SendMessage()");
if (m_hThread)
PostThreadMessage(m_nThreadID, Msg, wParam, lParam);
}

void WorkThread::SetPriority(int priority)
{
OutputDebugString("WorkThread::SetPriority()");
if (m_hThread)
SetThreadPriority(m_hThread, priority);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////NetClient

NetClient::NetClient()
{
m_socket = NULL;
m_pComKey = NULL;
}

NetClient::NetClient(int socket)
{
m_socket = socket;
}

NetClient::~NetClient()
{
if(m_socket)
closesocket(m_socket);
}

void NetClient::SendPacket(void* pData,bool encrypt)
{
g_pHostServer->SendPacket(m_socket,pData,encrypt);
}

void NetClient::Disconnect()
{
if(m_socket)
{
closesocket(m_socket);
m_socket = NULL;
}
}
udknight 2009-06-11
  • 打赏
  • 举报
回复
下面是NetCompletionPort类的代码
NetCompletionPort.h 代码

#ifndef _COMPLETIONPORT_H
#define _COMPLETIONPORT_H

#include <winsock2.h>
#include <mswsock.h>
#include <process.h>
#include <vector>
#include <map>
#include <deque>
#include <set>
#pragma comment (lib,"ws2_32.lib")

#define MAX_MEM_COUNT 1000
#define MAX_BUF 1024
#define RECV_COUNT 5

#pragma pack (push)
#pragma pack (1)

enum
{
IO_ACCEPT,
IO_READ,
IO_WRITE,
IO_END,
};

enum
{
IO_SEND,
IO_RECV
};


//单IO数据
typedef struct _PER_IO_CONTEXT
{
WSAOVERLAPPED ol;
char buf[MAX_BUF];
WSABUF wsabuf;
SOCKET sClient;
DWORD id;
BYTE IoOperation;
}PER_IO_CONTEXT,*LPPER_IO_CONTEXT;

//完成键(单句炳数据)
typedef struct _PER_HANDLE_CONTEXT
{
SOCKET IoSocket;

}PER_HANDLE_CONTEXT,*LPPER_HANDLE_CONTEXT;

static GUID g_GUIDAcceptEx = WSAID_ACCEPTEX;
static GUID g_GUIDGetAcceptExSockaddrs = WSAID_GETACCEPTEXSOCKADDRS;

class WorkThread
{
private:
HANDLE m_hThread;
unsigned int m_nThreadID;
unsigned int (__stdcall*pnThreadFun)(LPVOID param);
void* m_pParam;
public:
WorkThread();
WorkThread(unsigned int (__stdcall*pnThreadFun)(LPVOID param),void* param);
~WorkThread();
bool Init();
void Start();
void Stop();
void SendMessage(UINT Msg, WPARAM wParam, LPARAM lParam);
void SetPriority(int priority);
};

class NetClient
{
public:
SOCKET m_socket;
SOCKADDR_IN m_address;
LPPER_HANDLE_CONTEXT m_pComKey;
NetClient();
NetClient(int socket);
~NetClient();
void SendPacket(void* pData,bool encrypt = TRUE);
void Disconnect();
};



class NetCompletionPort
{
private:
LPFN_ACCEPTEX m_pAcceptEx;
LPFN_GETACCEPTEXSOCKADDRS m_pGetAcceptExSockaddrs;
HANDLE m_comPort;
int m_port;
SOCKET m_listenSocket;
WSAEVENT m_hEventListen;
bool m_isCreate;

std::vector<WorkThread*>* m_pWorkThreadList;
WorkThread* m_pThreadAccept;

bool InitWinSock();
bool InitListenSocket();
bool InitListenEvent();
bool InitWorkThread();

std::map<int,NetClient*>* m_pClientList;
CRITICAL_SECTION m_clientListSection;
void DeleteClient(NetClient* pClient);
void AddClient(NetClient* pClient);
NetClient* GetClient(int socket);

std::set<LPPER_IO_CONTEXT>* m_pConnectList;
CRITICAL_SECTION m_conSection;
void InsertConnect(LPPER_IO_CONTEXT pConnect);
void ReleaseConnect(int socket);

std::deque<LPPER_IO_CONTEXT>* m_pIoMemList;
std::deque<LPPER_HANDLE_CONTEXT>* m_pHandleMemList;
CRITICAL_SECTION m_ioMenListSection;
CRITICAL_SECTION m_hdMemListSection;
LPPER_IO_CONTEXT GetIoMem();
LPPER_HANDLE_CONTEXT GetHandleMem();
void InsertIoMem(LPPER_IO_CONTEXT pMem);
void InsertHandleMem(LPPER_HANDLE_CONTEXT pMem);

bool PostAcceptEx();

protected:
public:
NetCompletionPort();
virtual ~NetCompletionPort();
bool StartServer(int port);
void StopServer();

virtual bool Disconnect(int socket);
void SendPacket(int socket,void * pData,bool encrypt = TRUE);
virtual void EncryptPacket(void * pData,int & length,BYTE type,bool encrypt = TRUE);
virtual void RecvData(void * pData,NetClient* pClient);

void AcceptEvent(LPPER_IO_CONTEXT pIo,LPPER_HANDLE_CONTEXT pHd,DWORD dwByte);
void SendEvent(LPPER_IO_CONTEXT pIo,LPPER_HANDLE_CONTEXT pHd,DWORD dwByte);
void RecvEvent(LPPER_IO_CONTEXT pIo,LPPER_HANDLE_CONTEXT pHd,DWORD dwByte);
void CloseEvent(LPPER_IO_CONTEXT pIo,LPPER_HANDLE_CONTEXT pHd);

static unsigned __stdcall WorkThreadFun(LPVOID param);
static unsigned __stdcall AcceptThreadFun(LPVOID param);

};

#pragma pack (pop)

#endif

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧