************************请教关于完成端口的问题**************************

ControlCOder86 2006-12-08 03:07:01
我在写完成端口代码时这样做的
class CClientContext
{
private:
OVERLAPPED *m_pol;
WSABUF *m_pwbuf;


int m_nTotalBytes;
int m_nSendBytes;


SOCKET m_Socket;
int m_nOpCode;
char m_szBuffer[MAX_BUFFER_LEN];

public:
void SetOpCode(int n)
{
this->m_nOpCode = n;
}

int GetOpCode()
{
return this->m_nOpCode;
}

void SetTotalBytes(int n)
{
this->m_nTotalBytes = n;
}

int GetTotalBytes()
{
return this->m_nTotalBytes;
}

void SetSentBytes(int n)
{
this->m_nSendBytes = n;
}

void IncrSentBytes(int n)
{
this->m_nSendBytes += n;
}

int GetSendBytes()
{
return this->m_nSendBytes;
}

void SetSocket(SOCKET s)
{
this->m_Socket = s;
}

SOCKET GetSocket()
{
return this->m_Socket;
}

void SetBuffer(char *szBuffer)
{
strcpy(this->m_szBuffer,szBuffer);
}

void GetBuffer(char *szBuffer)
{
strcpy(szBuffer,this->m_szBuffer);
}

void ZeroBuffer()
{
ZeroMemory(this->m_szBuffer,MAX_BUFFER_LEN);
}

void SetWSABufferLength(int nLen)
{
this->m_pwbuf->len = nLen;
}

int GetWSABUFLength()
{
return this->m_pwbuf->len;
}

WSABUF* GetWSABUFPtr()
{
return this->m_pwbuf;
}

OVERLAPPED* GetOVERLAPPEDPtr()
{
return this->m_pol;
}

void ResetWSABUF()
{
this->ZeroBuffer();
this->m_pwbuf->buf = this->m_szBuffer;
this->m_pwbuf->len = MAX_BUFFER_LEN;
}

CClientContext()
{
this->m_pol = new OVERLAPPED;
this->m_pwbuf = new WSABUF;

ZeroMemory(this->m_pol,sizeof(OVERLAPPED));

this->m_Socket = SOCKET_ERROR;

ZeroMemory(this->m_szBuffer,MAX_BUFFER_LEN);

this->m_pwbuf->buf = this->m_szBuffer;
this->m_pwbuf->len = MAX_BUFFER_LEN;

this->m_nOpCode = 0;
this->m_nTotalBytes = 0;
this->m_nSendBytes = 0;
}


~CClientContext()
{
while(!HasOverlappedIoCompleted(this->m_pol))
{
Sleep(0);
}

closesocket(this->m_Socket);
delete this->m_pol;
delete this->m_pwbuf;
}
};

HANDLE g_hShutDownEvent = NULL;
int g_nThreads = 0;
HANDLE *g_phWorkerThreads = NULL;
HANDLE g_hAcceptThread = NULL;
HANDLE g_hBeginWorkerEvent = NULL;
WSAEVENT g_hAcceptEvent;
SOCKET listenSocket;


CRITICAL_SECTION g_csConsole;
CRITICAL_SECTION g_csClientList;

HANDLE g_hIOCompletionPort = NULL;

std::vector<CClientContext *> g_ClientContext;

g_nThreads = WORKER_THREADS_PER_PROCESSOR * GetNoOfProcessors();

g_phWorkerThreads = new HANDLE[g_nThreads];

InitializeCriticalSection(&g_csConsole);
InitializeCriticalSection(&g_csClientList);

g_hShutDownEvent = CreateEvent(NULL , TRUE , FALSE , NULL);
g_hBeginWorkerEvent = CreateEvent(NULL , TRUE , FALSE , NULL);

WSADATA wsaData;
int nResult;

nResult = WSAStartup(0x0202,&wsaData);
if(nResult!=0)
{
AfxMessageBox(IDS_ERROR_INIATESOCKET);
return false;
}
if(wsaData.wVersion!=0x0202)
{
AfxMessageBox(IDS_ERROR_INIATESOCKET);
return false;
}

listenSocket;
SOCKADDR_IN sockAddr;

listenSocket = WSASocket(AF_INET ,SOCK_STREAM , 0 , NULL , 0 , WSA_FLAG_OVERLAPPED);

if(listenSocket==INVALID_SOCKET)
{
AfxMessageBox(IDS_ERROR_INIATESOCKET);
goto error;
}


sockAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(SERVERPORT);

if(bind(listenSocket , (SOCKADDR *)&sockAddr , sizeof(sockAddr)) == SOCKET_ERROR)
{
AfxMessageBox(IDS_ERROR_BINDPORT);
goto error;
}

if(listen(listenSocket,SOMAXCONN)==SOCKET_ERROR)
{
AfxMessageBox(IDS_ERROR_WHENLISTEN);
goto error;
}

g_hAcceptEvent = WSACreateEvent();

if(WSA_INVALID_EVENT==g_hAcceptEvent)
{
AfxMessageBox(IDS_ERROR_CREATEEVENT);

goto error;
}

if(SOCKET_ERROR==WSAEventSelect(listenSocket , g_hAcceptEvent , FD_ACCEPT))
{
AfxMessageBox(IDS_ERROR_BINDEVENT);
goto error;
}


DWORD nThreadID;
g_hAcceptThread = CreateThread(0 ,0 ,AcceptThread , (LPVOID)listenSocket , 0 , &nThreadID);

if(!InitializeIOCP())
{
AfxMessageBox(IDS_ERROR_CREATEIOCOMPLETION);
goto error;
}




error:
closesocket(listenSocket);
WSACleanup();
return false;


...全文
247 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
ControlCOder86 2006-12-08
  • 打赏
  • 举报
回复
不要光接分不帮忙啊
GDI_GTK 2006-12-08
  • 打赏
  • 举报
回复
JF
ControlCOder86 2006-12-08
  • 打赏
  • 举报
回复
可是我发现

只要服务器一启动

WorkerThread里的GetQueuedCompletionStatus马上会返回false
并且cpu达到100%
所以我加了
if(WaitForSingleObject(g_hBeginWorkerEvent,5000)==WAIT_TIMEOUT)

在有客户端连过来的时候,GetQueuedCompletionStatus返回false
我用GetLastError得到的是998的错误代码

并且客户端发消息过来
server这里根本没反应

请问是什么地方的问题啊
ControlCOder86 2006-12-08
  • 打赏
  • 举报
回复
bool CSocket_2Dlg::InitializeIOCP()
{
g_hIOCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE , NULL , 0 , 0);
if(NULL==g_hIOCompletionPort)
{
AfxMessageBox(IDS_ERROR_CREATEIOCOMPLETION);
return false;
}

DWORD nThreadID;
for(int count = 0 ; count <g_nThreads ; count ++)
{
g_phWorkerThreads[count] = CreateThread(0 , 0 ,WorkerThread , (LPVOID)(count + 1) , 0 ,&nThreadID);
}

return true;
}



DWORD WINAPI AcceptThread(LPVOID lParam)
{
WSANETWORKEVENTS WSAEvents;

while(WAIT_OBJECT_0 != WaitForSingleObject(g_hShutDownEvent , 0))
{
if(WSA_WAIT_TIMEOUT != WSAWaitForMultipleEvents(1 , &g_hAcceptEvent , FALSE , 5000 , FALSE))
{
WSAEnumNetworkEvents(listenSocket , g_hAcceptEvent , &WSAEvents);

if ((WSAEvents.lNetworkEvents && FD_ACCEPT) && ( 0 == WSAEvents.iErrorCode[FD_ACCEPT_BIT]))
{
AcceptConnection();
}
}
}

return 1;
}


void AcceptConnection()
{
SOCKADDR_IN clientAddr;
int len = sizeof(clientAddr);

SOCKET socket = WSAAccept(listenSocket , (SOCKADDR*)&clientAddr ,&len , NULL , 0);
if (socket == INVALID_SOCKET)
{
AfxMessageBox(IDS_ERROR_ACCEPTSOCKET);
return;
}

CClientContext *pClientContext = new CClientContext();
pClientContext->SetOpCode(OP_READ);
pClientContext->SetSocket(socket);

AddToClientList(pClientContext);

if(AssociateWithIOCP(pClientContext) == true)
{
pClientContext->SetOpCode(OP_WRITE);

WSABUF *p_wbuf = pClientContext->GetWSABUFPtr();
OVERLAPPED *p_ol = pClientContext->GetOVERLAPPEDPtr();

DWORD dwFlags = 0;
DWORD dwBytes = 0;

int nBytesRecv = WSARecv(pClientContext->GetSocket() , p_wbuf , 1 , &dwBytes , &dwFlags , p_ol , NULL);

/* int error = WSAGetLastError();
char errors[10];
itoa(error,errors,10);
AfxMessageBox(errors);*/

if(WaitForSingleObject(g_hBeginWorkerEvent,0) != WAIT_OBJECT_0)
{
SetEvent(g_hBeginWorkerEvent);
}

if((SOCKET_ERROR == nBytesRecv) && (WSA_IO_PENDING != WSAGetLastError()))
{
AfxMessageBox(IDS_ERROR_RECV);
}

}

}
bool AssociateWithIOCP(CClientContext *pClientContext)
{
HANDLE temp = CreateIoCompletionPort((HANDLE)pClientContext->GetSocket() , g_hIOCompletionPort , (DWORD)pClientContext->GetOVERLAPPEDPtr() , 0);

if(temp == NULL)
{
RemoveFromClientListAndFreeMemory(pClientContext);
return false;
}

return true;

}

DWORD WINAPI WorkerThread(LPVOID lpParam)
{
int nThreadID = (int)lpParam;
void *lpContext = NULL;
OVERLAPPED *pOverlapped = NULL;
CClientContext *pClientContext = NULL;
DWORD dwBytesTransfered = 0;
int nBytesRecv = 0;
int nBytesSent = 0;
DWORD dwBytes = 0;
DWORD dwFlags = 0;

while(WAIT_OBJECT_0 != WaitForSingleObject(g_hShutDownEvent,0))
{
if(WaitForSingleObject(g_hBeginWorkerEvent,5000)==WAIT_TIMEOUT)
{
continue;
}

BOOL bReturn = GetQueuedCompletionStatus(
g_hIOCompletionPort,
&dwBytesTransfered,
(PULONG_PTR)lpContext,
&pOverlapped,
INFINITE);

int code = WSAGetLastError();
char codes[10];
itoa(code,codes,10);

AfxMessageBox(codes);

if(NULL == lpContext)
{
break;
}

pClientContext = (CClientContext *)lpContext;

if((bReturn == false) || ((bReturn == TRUE) && (dwBytesTransfered == 0)))
{
RemoveFromClientListAndFreeMemory(pClientContext);
AfxMessageBox(WSAGetLastError());
continue;
}

AfxMessageBox("tt");


}


return 1;
}


18,363

社区成员

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

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