IOCP投递进行读操作

IOCP投递读操作

当前位置: 开发语言频道 > 开发语言 > VC/MFC > 网络编程 > 为什么我的IOCP投递读操作,却收不到数据???
wqrz 发表于 2006-4-18 5:37:37


UINT CIocp::IoWorkerThread(LPVOID lParam)
{

CIocp* pThis = reinterpret_cast(lParam);
ASSERT(pThis);

HANDLE hIocp = pThis->m_hIocp;

DWORD dwIoSize;
ClientContext* lpClientContext=NULL;
OVERLAPPEDPLUS *pOverlapPlus=NULL;
LPOVERLAPPED lpOverlapped=NULL;
bool bError=false;

while(!bError)
{
pOverlapPlus=NULL;
lpClientContext=NULL;

BOOL bIORet = GetQueuedCompletionStatus(
hIocp,
&dwIoSize,
(LPDWORD) &lpClientContext,
&lpOverlapped, INFINITE);
//--------------------------------------------------------

if (bIORet==FALSE
&& lpOverlapped == NULL)
{
DebugPrint("IoWorkerThread - GetQueuedCompletionStatus()错误");
bError=TRUE;
}
else if (bIORet == FALSE
&& lpOverlapped != NULL)
{
// This happens occasionally instead of end-of-file. Not sure why.
closesocket(lpClientContext->m_hSocket);
delete lpClientContext;
DebugPrint("用户非正常退出");
}
else if (bIORet==0)
{
closesocket(lpClientContext->m_hSocket);
delete lpClientContext;
DebugPrint("用户已经关闭端口");
}
//--------------------------------------------------------
if(bIORet && lpOverlapped && lpClientContext)
{
pOverlapPlus=CONTAINING_RECORD(lpOverlapped, OVERLAPPEDPLUS, m_ol);
if(pOverlapPlus!=NULL)
pThis->ProcessIOMessage(pOverlapPlus, lpClientContext, dwIoSize);
}
//--------------------------------------------------------
if(lpClientContext==NULL && pOverlapPlus==NULL && pThis->m_bShutDown)
{
TRACE("lpClientContext==NULL /r/n");
bError=true;
}
//--------------------------------------------------------
if(bError==FALSE)
{
// 投递一个读操作
OVERLAPPEDPLUS * pOverlapPlus = new OVERLAPPEDPLUS(IORead);
ULONGulFlags = MSG_PARTIAL;

UINT nRetVal = WSARecv(lpClientContext->m_hSocket,
&lpClientContext->m_wsaInBuffer,
1,
&dwIoSize,
&ulFlags,
&pOverlapPlus->m_ol,
NULL);

if ( nRetVal == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
{
//pThis->RemoveStaleClient( lpClientContext, FALSE );
}
}
//--------------------------------------------------------
if(pOverlapPlus) delete pOverlapPlus;
//--------------------------------------------------------
}//while
TRACE("IOWorker Died!");
return 0xdead;
}

**************************************************
struct ClientContext
{
SOCKETm_hSocket;
DWORDm_dwID;
// Input Elements for Winsock
WSABUFm_wsaInBuffer;

// Output elements for Winsock
WSABUFm_wsaOutBuffer;


void NewInBuffer(DWORD nSize)
{
m_wsaInBuffer.buf = (CHAR*) new BYTE[nSize];
}

void NewOutBuffer(DWORD nSize)
{
m_wsaOutBuffer.buf = (CHAR*) new BYTE[nSize];
}

void FreeInBuffer()
{
//delete m_wsaInBuffer.buf;
m_wsaInBuffer.buf=NULL;
}

void FreeOutBuffer()
{
//delete m_wsaOutBuffer.buf;
m_wsaOutBuffer.buf=NULL;
}
};
************************************************************
void CIocp::OnAccept()
{
ClientContext* pClient=NULL;
SOCKETclientSocket=INVALID_SOCKET;

intnRet=-1;

clientSocket = accept(m_hListen,NULL,NULL);
ASSERT(clientSocket!=SOCKET_ERROR);

pClient = AllocateClient();
pClient->m_hSocket = clientSocket;
m_nIndex++;
pClient->m_dwID=m_nIndex;
pClient->NewInBuffer(1024);
........
}
*****************************************************************
void CIocp::ProcessIOMessage( OVERLAPPEDPLUS *pOverlapPlus, ClientContext* pClient, DWORD dwSize)
{
if(pOverlapPlus==NULL)
return;

switch (pOverlapPlus->m_ioType)
{
case IORead :
OnRead(pClient,dwSize);
break;
.......
}
}
***********************************************************

void CIocp::OnRead(ClientContext* pClient, DWORD dwSize)
{
if (dwSize == 0)
{
//RemoveStaleClient( pContext, FALSE );
return;
}
PostMessage(m_hWnd,WM_SOCKET_READ,pClient->m_dwID,(LPARAM)pClient->m_wsaInBuffer.buf);
}

***********************************************************************
wqrz 发表于 2006-4-18 5:42:20

和读操作有关的结构和函数基本都在上面了
我调试的时候投递一个读操作 可是OnRead的第2个参数dwSize老是0 导致无法收到任何信息
不知道是什么原因dwSize老是0呢?

现在这个类发送消息基本没问题了 就是接收信息接不到

如果上面代码还完整的话 谁有兴趣看一下整个工程文件 请留下邮箱~
gohappy_1999 发表于 2006-4-18 9:02:26

// 投递一个读操作
OVERLAPPEDPLUS * pOverlapPlus = new OVERLAPPEDPLUS(IORead);
ULONG ulFlags = MSG_PARTIAL;
/
memset(&pOverlapPlus->m_ol, 0, sizeof(pOverlapPlus->m_ol));
/
UINT nRetVal = WSARecv(lpClientContext->m_hSocket,
&lpClientContext->m_wsaInBuffer,
1,
&dwIoSize,
&ulFlags,
&pOverlapPlus->m_ol,
NULL);
wqrz 发表于 2006-4-18 9:13:27

不是楼上的XD讲的问题:
class OVERLAPPEDPLUS
{
public:
OVERLAPPEDm_ol;
IOTypem_ioType;

OVERLAPPEDPLUS(IOType ioType) {
ZeroMemory(this, sizeof( OVERLAPPEDPLUS));
m_ioType = ioType;
}
};
wqrz 发表于 2006-4-20 8:44:00
UP ~~~~~~~~~
gohappy_1999 发表于 2006-4-20 9:25:00
投递WSARecv后返回的错误码是多少?
wqrz 发表于 2006-4-20 9:41:00
WSARecv后应该没错误 因为WSARecv这句后的if条件不成立:

if ( nRetVal == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
{
//pThis->RemoveStaleClient( lpClientContext, FALSE );
}
wqrz 发表于 2006-4-20 11:32:00
搞定了 m_wsaInBuffer.len没赋值
快速回复
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值