模型设计与实践---(七)重叠IO ,完成例程

socketOverlappedCP.h

/********************************************************************
	创建时间:	2013/04/11

	文件名: 	socketOverlappedCP.h
	描述:
			重叠I/O 完成例程模式
	作者:		fengsh
	QQ  :		19985430
	电子邮件:	fengsh998@163.com
	Blog :      http://blog.csdn.net/fengsh998
	@CopyRight  fengsh

*********************************************************************/
#pragma once
#include "socketbase.h"

typedef struct tagOVERLAPPEDCP
{
	WSAOVERLAPPED overlap;
	WSABUF Buffer;
	char buf[BUFFERMAX];
	DWORD dwNumOfBytesRecved;
	DWORD Flags;
	SOCKET stClient; //比事件通知多了一个套接字
	void* context; //上下文句柄
}PER_OVERLAPPEDCP_DATA,*LPPER_OVERLAPPEDCP_DATA;

class CSocketOverlappedCP :
	public CSocketBase
{
public:
	CSocketOverlappedCP(void);
	~CSocketOverlappedCP(void);

	int startServer() ;
	int stopServer() ;
	bool sendtext(const std::string& content) ;

	void doOverlapDataListen(SOCKET client);
	void destroyedOverLappedDataByIndex(int idx);
	void destroyedOverLappedData();
	void adjustOverlappedData(int idx);
	int getIndexBySocket(SOCKET selclient);

	void doOverlappedCallback(DWORD dwError,DWORD csTransferred, 
		LPWSAOVERLAPPED lpOverlappped,DWORD dwFlags);

	LPPER_OVERLAPPEDCP_DATA m_overdata[MAXIMUM_WAIT_OBJECTS];
	int m_count;
private:
	void *wcid;
};


socketOverlappedCP.cpp

#include "socketOverlappedCP.h"
#include "socketThread.h"

void CALLBACK CompletionCallBack(DWORD dwError,DWORD csTransferred,
								LPWSAOVERLAPPED lpOverlappped,DWORD dwFlags);

static void* wait_client_thread(void* param);

CSocketOverlappedCP::CSocketOverlappedCP(void):m_count(0),wcid(0)
{
}

CSocketOverlappedCP::~CSocketOverlappedCP(void)
{
}

void CSocketOverlappedCP::doOverlapDataListen( SOCKET client )
{
	m_overdata[m_count] = (LPPER_OVERLAPPEDCP_DATA)HeapAlloc(GetProcessHeap(),
		HEAP_ZERO_MEMORY,sizeof(PER_OVERLAPPEDCP_DATA));

	m_overdata[m_count]->Buffer.buf = m_overdata[m_count]->buf;
	m_overdata[m_count]->Buffer.len = BUFFERMAX;
	m_overdata[m_count]->stClient = client;
	m_overdata[m_count]->context = this;

	WSARecv(client,&m_overdata[m_count]->Buffer,1,
		&m_overdata[m_count]->dwNumOfBytesRecved,&m_overdata[m_count]->Flags,
		&m_overdata[m_count]->overlap,CompletionCallBack);
	m_count++;
}

int CSocketOverlappedCP::startServer()
{
	if (initSocket())
	{
		socket_thread_create(&wcid,wait_client_thread,(void*)this);

		return 1;
	}
	return -1;
}

int CSocketOverlappedCP::stopServer()
{
	dispatchcallback(cbServerClose,NULL);

	closesocket(m_listenSocket);
	destroyedOverLappedData();
	return 1;
}

bool CSocketOverlappedCP::sendtext( const std::string& content )
{
	for (int i = 0;i < m_count; i++)
	{
		sendData(m_overdata[i]->stClient,content);
	}
	return true;
}

void CSocketOverlappedCP::destroyedOverLappedData()
{
	for (int i = 0;i < m_count; i++)
	{
		destroyedOverLappedDataByIndex(i);
	}

	m_count = 0;
}

void CSocketOverlappedCP::destroyedOverLappedDataByIndex( int idx )
{
	closesocket(m_overdata[idx]->stClient);
	HeapFree(GetProcessHeap(),0,m_overdata[idx]);
}

void CSocketOverlappedCP::adjustOverlappedData( int idx )
{
	if (idx < m_count - 1)
	{
		m_overdata[idx] = m_overdata[m_count - 1];
	}

	m_overdata[--m_count] = NULL;
}

void CSocketOverlappedCP::doOverlappedCallback( DWORD dwError,DWORD csTransferred, LPWSAOVERLAPPED lpOverlappped,DWORD dwFlags )
{
	LPPER_OVERLAPPEDCP_DATA lperIOData=(LPPER_OVERLAPPEDCP_DATA)lpOverlappped;
	DISPATCHPARAM dp;
	memset(&dp,0,sizeof(DISPATCHPARAM));
	
	if (dwError != 0 || csTransferred == 0)
	{
		int idx = getIndexBySocket(lperIOData->stClient);
		if (idx != -1)
		{
			destroyedOverLappedDataByIndex(idx);
			adjustOverlappedData(idx);
			dispatchcallback(cbDisconnect,NULL);
		}
	}
	else
	{
		strcpy(dp.msg,lperIOData->buf);
		//回调到界面
		dispatchcallback(cbCommunication,&dp);
		//回调到接收完成
		dispatchcallback(cbRecviced,NULL);

		memset(&lperIOData->overlap,0,sizeof(WSAOVERLAPPED));
		lperIOData->Buffer.len = BUFFERMAX;
		lperIOData->Buffer.buf = lperIOData->buf;

		WSARecv(lperIOData->stClient,&lperIOData->Buffer,1,
			&lperIOData->dwNumOfBytesRecved,&lperIOData->Flags,
			&lperIOData->overlap,CompletionCallBack);

	}
}

int CSocketOverlappedCP::getIndexBySocket( SOCKET selclient )
{
	int pos = -1;
	for (int i = 0; i < m_count ;i++)
	{
		if (m_overdata[i]->stClient == selclient)
		{
			pos = i;
			break;
		}
	}

	return pos;
}

static void* wait_client_thread(void* param)
{
	CSocketOverlappedCP *lapcp = (CSocketOverlappedCP*)param;

	DISPATCHPARAM dp;
	memset(&dp,0,sizeof(DISPATCHPARAM));
	SOCKET socketClient;

	while(true)
	{

		SOCKADDR_IN addrClient;
		int addrClientSize=sizeof(SOCKADDR_IN);
		socketClient=accept(lapcp->m_listenSocket,(struct sockaddr*)&addrClient,&addrClientSize);
		if (socketClient==INVALID_SOCKET)
		{
			socketClient = NULL;
			if (lapcp->checkSocketError(WSAGetLastError()))
			{
				break;
			}
			continue;
		}
		else
		{
			lapcp->doOverlapDataListen(socketClient);

			strcpy(dp.info.ip,inet_ntoa(addrClient.sin_addr));
			dp.info.port = addrClient.sin_port;
			lapcp->dispatchcallback(cbHasConnect,&dp);
		}
	}

	return 0;

}

//回到实例内部处理
void CALLBACK CompletionCallBack(DWORD dwError,DWORD csTransferred, 
								LPWSAOVERLAPPED lpOverlappped,DWORD dwFlags)
{
	LPPER_OVERLAPPEDCP_DATA lperIOData=(LPPER_OVERLAPPEDCP_DATA)lpOverlappped;

	CSocketOverlappedCP * overcp = NULL;
	if (lperIOData->context != NULL)
	{
		overcp = (CSocketOverlappedCP*)lperIOData->context;
		overcp->doOverlappedCallback(dwError,csTransferred,lpOverlappped,dwFlags);
	}

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

边缘998

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值