⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iocpcontext.cpp

📁 iocp vc例子,自己是学DELPHI
💻 CPP
字号:
// IocpContext.cpp: implementation of the CIocpContext class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "IocpContext.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CIocpContext::CIocpContext()
{
	m_soContext = INVALID_SOCKET;
	m_nNumberOfPengingIo = 0;
	m_nPosition = NULL;	
	m_ulKey = 0;
	m_pIocpMngr = NULL;

	m_nSendSequenceNumber = m_nCurrentSendSequenceNumber = 0;
	m_nRecvSequenceNumber = m_nCurrentRecvSequenceNumber = 0;

	m_mapSendBuffer.InitHashTable(MAXHASHSIZE);
	m_mapRecvBuffer.InitHashTable(MAXHASHSIZE);
}

CIocpContext::~CIocpContext()
{
	FreePacket();
}

int CIocpContext::EnterIoLoop()
{
	m_csContext.Lock();
	int nNumberOfPendingIo=m_nNumberOfPengingIo++;
	m_csContext.Unlock();
	return nNumberOfPendingIo;
}

int CIocpContext::ExitIoLoop()
{
	m_csContext.Lock();
	m_nNumberOfPengingIo--;
	int nNumberOfPendingIo=m_nNumberOfPengingIo;
	m_csContext.Unlock();
	return nNumberOfPendingIo;
}

CIocpPacket* CIocpContext::FindPacket(ULONG ulKey, WORD wType)
{
	CIocpPacket* pRet=NULL;	
	//从使用的网络包数据中查找
	m_csUsedPacket.Lock();
	for (POSITION pos=m_plUsedPacket.GetHeadPosition(); pos!=NULL;)
	{
		CIocpPacket* pPacket=(CIocpPacket*)m_plUsedPacket.GetNext(pos);
		if (pPacket!=NULL && pPacket->m_ulKey==ulKey && pPacket->m_wType==wType)
		{
			pRet = pPacket;
			break;
		}
	}
	m_csUsedPacket.Unlock();
	return pRet;
}

CIocpPacket* CIocpContext::AllocatePacket(ULONG ulKey, WORD wType)
{
	CIocpPacket* pRet=NULL;
	
	//查找空闲网络包
	m_csFreePacket.Lock();
	if (!m_plFreePacket.IsEmpty())
		pRet = (CIocpPacket*)m_plFreePacket.RemoveHead();
	m_csFreePacket.Unlock();
	
	//添加到使用的网络包数组中
	if (pRet==NULL) 
		pRet = new CIocpPacket();
	pRet->m_ulKey = ulKey;
	pRet->m_wType = wType;
	pRet->ResetPacket();
	m_csUsedPacket.Lock();
	m_plUsedPacket.AddHead(pRet);
	m_csUsedPacket.Unlock();
	
	return pRet;
}

void CIocpContext::ReleasePacket(ULONG ulKey, WORD wType)
{
	CIocpPacket* pPacket=FindPacket(ulKey, wType);
	if (pPacket!=NULL) ReleasePacket(pPacket);
}

void CIocpContext::ReleasePacket(CIocpPacket* pPacket)
{
	if (pPacket==NULL) return;	
	
	pPacket->ClosePacketFile();
	pPacket->DeleteAllFile();
	
	//从使用缓冲区数组中删除
	m_csUsedPacket.Lock();
	for (POSITION pos=m_plUsedPacket.GetHeadPosition(); pos!=NULL;)
	{
		POSITION oldpos=pos;
		CIocpPacket* pIocpPacket=(CIocpPacket*)m_plUsedPacket.GetNext(pos);
		if (pIocpPacket==pPacket)
		{
			m_plUsedPacket.RemoveAt(oldpos);
			break;
		}
	}
	m_csUsedPacket.Unlock();
	
	//添加到空闲缓冲区数组中
	m_csFreePacket.Lock();
	if (m_plFreePacket.GetCount()<MAX_NUMBER_OF_FREE_PACKET_LIST)
	{
		pPacket->ResetPacket();
		m_plFreePacket.AddHead(pPacket);
	}
	else
	{
		if (pPacket!=NULL) delete pPacket;
	}
	m_csFreePacket.Unlock();
}

void CIocpContext::FreePacket()
{
	m_csFreePacket.Lock();
	for (POSITION pos=m_plFreePacket.GetHeadPosition(); pos!=NULL;)
	{
		CIocpPacket* pPacket=(CIocpPacket*)m_plFreePacket.GetNext(pos);
		if (pPacket!=NULL) delete pPacket;
	}
	m_plFreePacket.RemoveAll();
	m_csFreePacket.Unlock();

	m_csUsedPacket.Lock();
	for (pos=m_plUsedPacket.GetHeadPosition(); pos!=NULL;)
	{
		CIocpPacket* pPacket=(CIocpPacket*)m_plUsedPacket.GetNext(pos);
		if (pPacket!=NULL) delete pPacket;
	}
	m_plUsedPacket.RemoveAll();
	m_csUsedPacket.Unlock();
}

ULONG CIocpContext::GenerateKey()
{
	m_csContext.Lock();	
	ULONG ulRet=m_ulKey*2+1;	//只有发送包才会调用此函数,保证了发送包的标识为单数
	m_ulKey = (m_ulKey+1) % MAXKEYNUMBER;	
	m_csContext.Unlock();
	return ulRet;
}

GUID CIocpContext::GenerateGuid()
{
	GUID gdRet=GUID_NULL;
	m_csContext.Lock();
	HRESULT hr=CoCreateGuid(&gdRet);
	ASSERT(SUCCEEDED(hr));
	m_csContext.Unlock();
	return gdRet;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -