完成端口消息的问题,解决完马上给分。

Leryan 2004-12-16 07:46:38
我用的是TCP协议,服务端创建listen socket.
m_socListener = WSASocket(
AF_INET,
SOCK_STREAM,
0,
NULL,
0,
WSA_FLAG_OVERLAPPED
);

我把客户端连接的socket 关联到完成端口之后,另外开启一个线程等待客户端的数据,
while(1)
{
BOOL bIORet = GetQueuedCompletionStatus(
m_hCompletionPort,
&dwIoSize,
(LPDWORD) &lpClientContext,
&lpOverlapped,
INFINITE);
if (!bIORet)
{
clear_err_socket(lpClientContext);
}

}

可是再客户端发送数据之后,GetQueuedCompletionStatus()函数没有唤醒,
或者说GetQueuedCompletionStatus()函数没有任何反映,
就是客户端再关闭时候调用
shutdown(clientSocket);
也不会收到任何消息。
请指教。

可以肯定的是我已经关联到完成端口了,而且客户端显示发送数据成功。
也就是数据已经到达服务器了,

...全文
206 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2005-04-14
  • 打赏
  • 举报
回复
如果get函数可以被正常阻塞的话,那问题应该出在wsarecv未被正常执行。
nuaawenlin 2005-04-14
  • 打赏
  • 举报
回复
在WSARecv()之后,判断错误是不是WSA_IO_PENDING.如果不是,就是你的参数有问题
windywalk 2004-12-17
  • 打赏
  • 举报
回复
你没有激发IOCP
在while循环里加上 ::WSAREcv();
来触发完成端口
needways 2004-12-16
  • 打赏
  • 举报
回复

m_socListener = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
改为
m_socListener = socket(AF_INET, SOCK_STREAM, 0);
Leryan 2004-12-16
  • 打赏
  • 举报
回复
// 以下是listen线程:
DWORD WINAPI
AcceptThread(LPVOID lParam)
{
while(1)
{
socClient = WSAAccept(
m_socListener,
NULL,
NULL, NULL, 0);
if ( socClient==INVALID_SOCKET )
{
break;
}
if ( CreateIoCompletionPort(
(HANDLE)socClient,
m_hCompletionPort,
(DWORD)pContext,
0) != m_hCompletionPort )
{
break;
}

ClientContextPtr pContext = new ClientContext();
pContext->socClient;

m_pContextList->Add(pContext);
OVERLAPPEDPLUS *pOverlap = new OVERLAPPEDPLUS(IOInitialize);

//这个消息GetQueuedCompletionStatus()正常接受到了。
//而且我观察GetQueuedCompletionStatus()调用得到的 pContext结构没有任何问题。
BOOL bSuccess = PostQueuedCompletionStatus
(
m_hCompletionPort,
0,
(DWORD) pContext,
&pOverlap->m_ol
);
if ( (!bSuccess && GetLastError() != ERROR_IO_PENDING) )
{
m_pContextList->Remove(pContext);
}
}
}

可要是客户端发送的网络消息GetQueuedCompletionStatus()
函数没有任何反应,
甚至客户端调用shutdown(clientSocket )也一样。
Leryan 2004-12-16
  • 打赏
  • 举报
回复
可能我表达的不是很清楚:
以下的我 认为时问题的关键,望各位帮忙看看时怎么回事。

在accept 完成之后
手工 GetQueuedCompletionStatus()的消息。
完成端口可以正常接受到消息,
可是就是不响应网络的消息,。
郁闷。

Leryan 2004-12-16
  • 打赏
  • 举报
回复
OVERLAPPEDPLUS * pOverlap = new OVERLAPPEDPLUS(IORead);
ULONG ulFlags = MSG_PARTIAL;

UINT nRetVal = WSARecv(
m_Socket,
&m_wsaInBuffer,
1,
&dwIoSize,
&ulFlags,
&pOverlap->m_ol,
NULL);

if ( nRetVal == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
{
// error.
return false;
}
HunterForPig 2004-12-16
  • 打赏
  • 举报
回复
首先socket要和completion port绑定
而后completion要和thread中的 GetQueuedCompletionStatus

确定了吗?
needways 2004-12-16
  • 打赏
  • 举报
回复
将你的 receive 部分贴上来看看。
Leryan 2004-12-16
  • 打赏
  • 举报
回复
在接受客户端连接后,要调用 Receive,或先 POST 一个消息手工激活。
等 Receive 到数据后 GetQueuedCompletionStatus() 就唤醒了。

已经激活了
而且能正常处理手工 POST 的消息。
但是就是不响应网络的消息,。
郁闷。
needways 2004-12-16
  • 打赏
  • 举报
回复
DWORD CALLBACK AcceptThreadProc(LPVOID pvArg)
{
SOCKET sock;

...

while(true)
{
sock = accept(...);

...

PostQueuedCompletionStatus(...);
}

return 0;
}

DWORD CALLBACK ThreadPoolProc(LPVOID pvArg)
{
BOOL bRet;

...

while(true)
{
bRet = GetQueuedCompletionStatus(...);

...

WSARecv(...)

...
}

return 0;
}
needways 2004-12-16
  • 打赏
  • 举报
回复
在接受客户端连接后,要调用 Receive,或先 POST 一个消息手工激活。
等 Receive 到数据后 GetQueuedCompletionStatus() 就唤醒了。
needways 2004-12-16
  • 打赏
  • 举报
回复
MSN: cwlstudio@hotmail.com
madhappy 2004-12-16
  • 打赏
  • 举报
回复
你的线程名有没有和完成端口关联起来?
Leryan 2004-12-16
  • 打赏
  • 举报
回复
555555
没有人回答,只好自己顶一下,要不帖子要沉了

18,356

社区成员

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

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