IOCP wsarecv调用等不到完成信息

maiomaio 2008-06-14 04:25:58
我是用WSASynSelect来得到有连接请求,然后左右socket都申请必要的内存并绑定到完成端口上.


switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
{
if ((socketAccept=WSAAccept(wParam,NULL,NULL,NULL,0)) == INVALID_SOCKET)
{
break;
}

socketServer=g_ThreadPool.CreateServerSocket( \
g_ThreadPool.m_MapInfo[wParam].DestIP, g_ThreadPool.m_MapInfo[wParam].DestPort);
if (INVALID_SOCKET==socketServer)
{

closesocket(socketAccept);
socketAccept=INVALID_SOCKET;
break;
}

pPerSocketContextClient=g_ThreadPool.UpdateCompletionPort(socketAccept,socketServer,IoRead,true);
if (NULL==pPerSocketContextClient)
{
break;
}

pPerSocketContextServer=g_ThreadPool.UpdateCompletionPort(socketServer,socketAccept,IoRead,true);
if (NULL==pPerSocketContextServer)
{
break;
}

nRet=WSARecv(socketAccept,&(pPerSocketContextClient->pPerIoContext->wsabuf),1,&dwRecvNumBytes, \
&dwFlag,&(pPerSocketContextClient->pPerIoContext->OverLapped),NULL);
if ((SOCKET_ERROR==nRet) && (ERROR_IO_PENDING!=WSAGetLastError()))
{
g_ThreadPool.FreeAndCloseSocket(pPerSocketContextClient);
break;
}

nRet2=WSARecv(socketServer,&(pPerSocketContextServer->pPerIoContext->wsabuf),1,&dwRecvNumBytes2, \
&dwFlag2,&(pPerSocketContextServer->pPerIoContext->OverLapped),NULL);
if ((SOCKET_ERROR==nRet2) && (ERROR_IO_PENDING!=WSAGetLastError()))
{
g_ThreadPool.FreeAndCloseSocket(pPerSocketContextServer);
break;
}
break;
...全文
182 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
maiomaio 2008-06-15
  • 打赏
  • 举报
回复
不知道用WSAAsynSelect来配合IOCP,可不可以,我几百行代码,调了很久了,郁闷死了,准备选楼了
cppwin 2008-06-15
  • 打赏
  • 举报
回复
建议改用AcceptEx.从来没有看到过有人用WSAAsynSelect 来配合IOCP的.
maiomaio 2008-06-15
  • 打赏
  • 举报
回复
本来想用ACCeptEx的,看了一下,好象不大好做,时间又紧,所以先用WSAAsynSelect,过渡一下,先实现功能,再说....
scq2099yt 2008-06-15
  • 打赏
  • 举报
回复
up
cppwin 2008-06-15
  • 打赏
  • 举报
回复
为什么不用 AcceptEx, 却用 WSAAsyncSelect ?
僵哥 2008-06-15
  • 打赏
  • 举报
回复
就Accept而言,无所谓你使用什么方式,只是Accept得到的Socket首先需要支持Overlapped操作,在连接之后CreateIOCompletionPort与完成端口相关联,所有需要通过完成端口得到完成通知的操作采用支持Overlapped的操作接口,并且带有有效Overlapped结构。
maiomaio 2008-06-14
  • 打赏
  • 举报
回复
上面是工作线程的主要代码,首先是等到接收数据成功的信号,然后就把接到的数据转发出去,全部转发完了(在IOWRITE中判断),就再调用WSARecv继续接收数据
不知道我这样会不会出问题

//////////////////////////////////////////////////////
我现在的问题是:
1.我用WSASynSelect的FD_ACCEPT判断如果有连接要求,我就会接受,然后建立连接到映射的目的地的socket,再把两个sokcet绑定到iocp,并第一次调用WSARecv.当工作线程等到WSARecv完成后就把接到的数据转发出去,等数据转发完后我就再次调用WSARecv,可是这次调用,在IOCP等不到完成信号.
2.还有我判断客户端soket有没有关闭是通过判断GetQueuedCompletionStatus();的返回值是不是为0或者不为了但收到的数据为0,我就认为客户端socket关闭了,我就把两端的socket都关闭,不知道有没有问题,
maiomaio 2008-06-14
  • 打赏
  • 举报
回复
while (TRUE)
{
bSuccess=GetQueuedCompletionStatus(hIOCP,&dwIOBytes,(DWORD*)&pPerSocketContext,&lpOverlapped,INFINITE);
if (NULL==pPerSocketContext)
{
return 0;
}

if ((!bSuccess) || (bSuccess && 0==dwIOBytes))
{
pThis->FreeAndCloseSocket(pPerSocketContext);
continue;
}
pPerIoContext=(PPER_IO_CONTEXT)lpOverlapped;
switch(pPerIoContext->IoOperation)
{
case IoRead:
{
pPerIoContext->IoOperation=IoWrite;
pPerIoContext->nTotalBytes=dwIOBytes;
pPerIoContext->nSendBytes=0;
pPerIoContext->wsabuf.len=dwIOBytes;
dwFlag=0;

nRet=WSASend(pPerSocketContext->pPerIoContext->SocketServer,&(pPerSocketContext->pPerIoContext->wsabuf),1 \
,&dwNumOfBytesSend,dwFlag,&(pPerSocketContext->pPerIoContext->OverLapped),NULL);
if ((SOCKET_ERROR==nRet) && (ERROR_IO_PENDING!=WSAGetLastError()))
{
pThis->FreeAndCloseSocket(pPerSocketContext);
break;

}
break;
}
case IoWrite:
{
dwFlag=0;
pPerIoContext->nSendBytes+=dwIOBytes;
pPerIoContext->IoOperation=IoWrite;

if (pPerIoContext->nSendBytes<pPerIoContext->nTotalBytes)
{
pPerIoContext->wsabuf.buf=pPerIoContext->wsabuf.buf+dwIOBytes;
pPerIoContext->wsabuf.len=pPerIoContext->wsabuf.len-dwIOBytes;

nRet=WSASend(pPerIoContext->SocketServer,&(pPerIoContext->wsabuf),1 \
,&dwNumOfBytesSend,dwFlag,&(pPerIoContext->OverLapped),NULL);
if ((SOCKET_ERROR==nRet) && (ERROR_IO_PENDING!=WSAGetLastError()))
{
pThis->FreeAndCloseSocket(pPerSocketContext);
}
}
else
{
dwFlag=0;
dwRecvNumBytes=0;

pPerSocketContext->pPerIoContext->IoOperation=IoRead;
pPerSocketContext->pPerIoContext->nSendBytes=0;
pPerSocketContext->pPerIoContext->nTotalBytes=0;
pPerSocketContext->pPerIoContext->OverLapped.hEvent=NULL;
pPerSocketContext->pPerIoContext->OverLapped.Internal=0;
pPerSocketContext->pPerIoContext->OverLapped.InternalHigh=0;
pPerSocketContext->pPerIoContext->OverLapped.Offset=0;
pPerSocketContext->pPerIoContext->OverLapped.OffsetHigh=0;
pPerSocketContext->pPerIoContext->wsabuf.len=sizeof(pPerSocketContext->pPerIoContext->Buffer);
ZeroMemory(pPerSocketContext->pPerIoContext->Buffer,sizeof(pPerSocketContext->pPerIoContext->Buffer));

nRet=WSARecv(pPerSocketContext->socketAccept,&(pPerSocketContext->pPerIoContext->wsabuf),1,&dwRecvNumBytes, \
&dwFlag,&(pPerSocketContext->pPerIoContext->OverLapped),NULL);
if ((SOCKET_ERROR==nRet) && (ERROR_IO_PENDING!=WSAGetLastError()))
{
pThis->FreeAndCloseSocket(pPerSocketContext);
break;
}
}
break;

}
default:
break;

18,356

社区成员

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

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