IOCP投递进行读操作

原创 2006年06月02日 17:17:00

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没赋值
快速回复

IOCP多次投递

iocp 的话 可以同时进行多次投递 这是没有问题的。 你可以同时投递读和写。 写的话  可以同时投递多个,而且 他会按照你投递的顺序进行发 送 理论上说iocp 如果同时多次投递send 如果某次没...
  • blade2001
  • blade2001
  • 2009年11月05日 13:14
  • 3642

iocp注意的几点

好久没写博客了。 Iocp,这次写文件监控,应该是第一次自己写,以前应该只是看吧,单单写注意点吧。 1、CreateIocompletionPort函数,有创建完成端口和关联完成端口两个功能。最后...
  • u012640985
  • u012640985
  • 2014年07月21日 19:52
  • 454

ReadDirectoryChangesW 监控文件夹 (一个简单的监控示例程序)

// .h文件 #pragma once typedef void (*PFN_NotifyAction)(DWORD dwAction, LPWSTR szFile, DWORD dwLength...
  • VisualEleven
  • VisualEleven
  • 2012年05月13日 12:31
  • 4860

在 windows IOCP 中,如何等待异步 IO 操作完成(包括被取消)[转]

在 windows IOCP 中,如何等待异步 IO 操作完成(包括被取消)[转] 关于 IOCP 中如何安全释放资源,我想关键点是在于如何等待异步 IO 完成,被取消也暂且认为是一种完成。 在使用多...
  • stormkey
  • stormkey
  • 2010年07月29日 22:31
  • 2293

IOCP 细节解说

【什么是IOCP】 是WINDOWS系统的一个内核对象。通过此对象,应用程序可以获得异步IO的完成通知。 这里有几个角色: 角色1:异步IO请求者线程。简单的说,就是调用WSAxxx...
  • FrankieWang008
  • FrankieWang008
  • 2014年03月28日 15:01
  • 914

iocp的简单实现

本文借助炽离的winsock编程IOCP模型实现代码进行进一步分析以及扩展。 本文主要使用到了以下几个知识点,1.标准模板库(stl)使用 2.多线程的使用3.单例等设计模式4.socket网络通讯...
  • xilango
  • xilango
  • 2018年01月29日 19:44
  • 47

select,IOCP模型实践 -- KC直播

背景利用笔记本的摄像头,采集环境信息,搭建高性能的视频监控模块。
  • guguant
  • guguant
  • 2017年06月13日 16:04
  • 366

IOCP 端口注意事项

IOCP 端口思想:  我们不停地发出异步的WSASend/WSARecv I/O操作,具体的I/O处理过程由WINDOWS系统完成,WINDOWS系统完成实际的IO处理后,  把结果送到完成端口...
  • liuhongxiangm
  • liuhongxiangm
  • 2012年06月20日 17:57
  • 1567

IOCP一:AcceptEx

IOCP
  • rongxiaojun
  • rongxiaojun
  • 2014年07月22日 16:45
  • 1659

[C++]监控特定文件夹的事件:三种解决方法汇总

监控特定文件夹的事件:三种解决方法汇总 LDBIVR程序中要监视特定文件夹的文件落地或者删除事件,本来要用SHELL中的事件通知机制,后来因为要考虑到各种意外事件,如服务意外退出、服务器崩溃等,遂...
  • huangkelong
  • huangkelong
  • 2008年04月12日 15:27
  • 278
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:IOCP投递进行读操作
举报原因:
原因补充:

(最多只允许输入30个字)