命名管道的封装类

class NamePipeOperate
{
public:
	//--------服务端函数--------------------------------------
	NamePipeOperate(const wchar_t *pPipeName,BOOL bAsync/*是否异步*/)throw(int);
	NamePipeOperate(HANDLE  hPipe,BOOL bAsync,BOOL bUnUsed)throw(int);
	//同步的话会等到客户端连接才会返回,异步的话调用完ConnectNamedPipe后马上返回;
	BOOL DoWaitClientStubAction();
	//只对异步操作有用;
	BOOL Wait(DWORD dwMilliseconds = -1);
    //----------------------------------------------------------

	//--------客户端函数----------------------------------------
	NamePipeOperate();
	// dwMilliseconds为NMPWAIT_WAIT_FOREVER为永久等待;
	BOOL Open(wchar_t *pExistPipeName,BOOL bAsync,DWORD dwMilliseconds = NMPWAIT_WAIT_FOREVER);
	//----------------------------------------------------------

	BOOL SendData(const BYTE* pdata,int nlen);
	BOOL ReadData(BYTE*pBuffer,int nLen);
	DWORD  GetTransferredNums();
	HANDLE GetAsyncEvent();
	HANDLE GetPipeHandle();
	BOOL ClosePipe();
	~NamePipeOperate();

protected:
	void InitValue();
private:
	HANDLE  m_hEvent;
	HANDLE  m_hpipe;
	OVERLAPPED m_overlapped;
	BOOL    m_bAsync;
	DWORD   m_dwTransferNum;
};


NamePipeOperate::NamePipeOperate(const wchar_t *pPipeName,BOOL bAsync)
{
	InitValue();

	if (!pPipeName)
	{
		throw(-1);
		return;
	}

	DWORD dwPipeMode = PIPE_ACCESS_DUPLEX;

	if (bAsync)
	{
		m_bAsync = TRUE;
		dwPipeMode |= FILE_FLAG_OVERLAPPED;
		m_hEvent    = CreateEvent(NULL, TRUE, FALSE, NULL);
		m_overlapped.hEvent = m_hEvent;
	}

	m_hpipe = CreateNamedPipeW(pPipeName, dwPipeMode, 
						  0, 1, 1024, 1024, 0, NULL);

	if(INVALID_HANDLE_VALUE == m_hpipe)
	{
		throw(-2);
		return;
	}	
}

/*
使用端: 服务端
  作用: 为了使pipe操作方便,将已经存在的pipe Handle套到该类中使用;
  参数: hPipe 管道handle,bAsync 是否是异步的,bUnUsed没有使用;
  备注: 当管道handle为NULL时会抛出-2异常;
*/
NamePipeOperate::NamePipeOperate(HANDLE hPipe, BOOL bAsync, BOOL bUnUsed)
{
	if (!hPipe)
	{
		throw(-2);
		return;
	}

	InitValue();

	m_hpipe = hPipe;
	m_bAsync = bAsync;

	if(bAsync)
	{
		m_hEvent    = CreateEvent(NULL, TRUE, FALSE, NULL);
		m_overlapped.hEvent = m_hEvent;
	}
}

/*
使用端: 客户端
  作用: 默认构造函数;
*/
NamePipeOperate::NamePipeOperate()
{
	InitValue();
}

/*
使用端: 客户端
  作用: 链接服务端的管道并制定客户端后续的操作是同步还是异步进行;
  参数: pExistPipeName 为服务端创建管道时制定的名字,bAsync是否是异步操作,dwMilliseconds为连接服务端等待时间默认值为无限等;
返回值: 成功返回TRUE,否则返回FALSE;
*/
BOOL NamePipeOperate::Open(wchar_t *pExistPipeName,BOOL bAsync,DWORD dwMilliseconds)
{
	if(!WaitNamedPipeW(pExistPipeName, dwMilliseconds))
	{
		return FALSE;
	}

	m_bAsync = bAsync;
	DWORD dwFlag = FILE_ATTRIBUTE_NORMAL;
	if (m_bAsync)
	{
		m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
		m_overlapped.hEvent = m_hEvent;
		dwFlag |= FILE_FLAG_OVERLAPPED;
	}
	
	m_hpipe = CreateFile(pExistPipeName, GENERIC_READ | GENERIC_WRITE, 
		0, NULL, OPEN_EXISTING,dwFlag, NULL);
	if(INVALID_HANDLE_VALUE == m_hpipe)
	{
		return FALSE;
	}

	return TRUE;
}

/*
使用端: 服务端,客户端
  作用: 异步操作之后使用。等待成功后表示上一次的异步操作的内容已经完成了;
  参数: dwMilliseconds为等待的时间,默认值为无限等;
返回值: 等待成功返回TRUE,否则返回FALSE;
*/
BOOL NamePipeOperate::Wait(DWORD dwMilliseconds)
{
	if(WAIT_OBJECT_0 == WaitForSingleObject(m_hEvent, dwMilliseconds))
	{
		return TRUE;
	}

	return FALSE;
}

/*
使用端: 服务端,客户端
  作用: 关闭管道;
返回值: 成功返回TRUE,否则返回FALSE;
*/
BOOL NamePipeOperate::ClosePipe()
{
	BOOL bRet = FALSE;
	if (m_hpipe)
	{
		bRet = CloseHandle(m_hpipe);
	}
	
	if (m_hEvent)
	{
		bRet &= CloseHandle(m_hEvent);
	}

	InitValue();
	return bRet;
}

/*
使用端: 服务端
  作用: 等待客户端连接;
返回值: 成功返回TRUE,否则返回FALSE;
*/
BOOL NamePipeOperate::DoWaitClientStubAction()
{
	if (m_bAsync)
	{
		if(!ConnectNamedPipe(m_hpipe, &m_overlapped))
		{
			if(ERROR_IO_PENDING != GetLastError())
			{
				return FALSE;
			}
		}

		return TRUE;
	}

   if (!ConnectNamedPipe(m_hpipe, NULL))
   {
	   return FALSE;
   }

   return TRUE;
}

HANDLE NamePipeOperate::GetAsyncEvent()
{
	return m_hEvent;
}

HANDLE NamePipeOperate::GetPipeHandle()
{
	return m_hpipe;
}

BOOL NamePipeOperate::SendData(const BYTE *pdata, int nlen)
{
	DWORD dwWrite = 0;

	if (m_bAsync)
	{
		ResetEvent(m_hEvent);
		if(!WriteFile(m_hpipe, pdata,nlen, &dwWrite,&m_overlapped))
		{
			if (GetLastError() != ERROR_IO_PENDING)
			{
				return FALSE;
			}
		}
	}
	else
	{
		if(!WriteFile(m_hpipe, pdata,nlen, &dwWrite, NULL))
		{
			return FALSE;
		}

		m_dwTransferNum = dwWrite;
	}
	
	return TRUE;
}


BOOL NamePipeOperate::ReadData(BYTE*pBuffer,int nLen)
{
	DWORD dwRead = 0;

	if (m_bAsync)
	{
		ResetEvent(m_hEvent);
		if(!ReadFile(m_hpipe, pBuffer, nLen,NULL, &m_overlapped))
		{
			if (GetLastError() != ERROR_IO_PENDING && GetLastError() != ERROR_MORE_DATA)
			{
				return FALSE;
			}
		}
	}
	else
	{
		if(!ReadFile(m_hpipe, pBuffer, nLen, &dwRead, NULL))
		{
			if (GetLastError() != ERROR_MORE_DATA)
			{
				return FALSE;
			}
		}
		m_dwTransferNum = dwRead;
	}
	
	return TRUE;
}

void NamePipeOperate::InitValue()
{
	m_hpipe = m_hEvent = NULL;
	memset(&m_overlapped,0,sizeof(m_overlapped));
	m_bAsync = FALSE;
	m_dwTransferNum = 0;
}


DWORD NamePipeOperate::GetTransferredNums()
{
	if (m_bAsync)
	{
		if (GetOverlappedResult(m_hpipe,&m_overlapped,&m_dwTransferNum,FALSE))
		{
			return m_dwTransferNum;
		}
	}
	else
	{
		return m_dwTransferNum;
	}

	return 0;
}

NamePipeOperate::~NamePipeOperate()
{
	if (m_hEvent)
	{
		CloseHandle(m_hEvent);
	}
}

服务端使用:

int main()
{
	wchar_t* szPipeName = L"\\\\.\\pipe\\Test_Pipe_007";

	NamePipeOperate serverPipe(szPipeName,TRUE);

	if (!serverPipe.DoWaitClientStubAction())
	{
		throw(-1);
	}

	/*
	   do some other things;
    */

	//wait client connect;
	if (!serverPipe.Wait())
	{
		printf("connect client error!");
		throw(-2);
	}

	FILE *pFileStream = _wfopen(L"E:\\Src.pdf",L"rb");
	if (!pFileStream)
	{
		throw(-3);
	}

	BYTE byBuffer[2];
	UINT32 uBufferSize = 2;

	for (;;)
	{
		size_t uReadSize = fread(byBuffer,1,uBufferSize,pFileStream);

		if (uReadSize <= 0)
		{
			break;
		}

		if (!serverPipe.SendData(byBuffer,uReadSize))
		{
			throw(-4);
		}
		
		/*
		do some other things;
		*/

		if (serverPipe.Wait())
		{
			//send success;
			if(serverPipe.GetTransferredNums() != uReadSize)
			{
				throw(-5);
			}
		}
		else
		{
			//send error;
			throw(-6);
		}
	}

	serverPipe.ClosePipe();
	return 0;
}

客户端使用:

int _tmain(int argc, _TCHAR* argv[])
{
	wchar_t* szPipeName = L"\\\\.\\pipe\\Test_Pipe_007";

	NamePipeOperate pipeclient;
	BOOL bRet = pipeclient.Open(szPipeName,TRUE);

	FILE *pFileStream = _wfopen(L"E:\\Result.pdf",L"wb");

	if (!pFileStream)
	{
		return 0;
	}

	if (bRet)
	{
		BYTE szWriteData[1024];

		while(1)
		{
			int nLen = 1024;
			BOOL bRet = pipeclient.ReadData(szWriteData,nLen);

			if (!bRet)
			{
				break;
			}

			if (pipeclient.Wait())
			{
				fwrite(szWriteData,1,pipeclient.GetTransferredNums(),pFileStream);
			}
			else
			{
				printf("Wait Error-----\n");
				break;
			}
		}
	}

	fclose(pFileStream);
	pipeclient.ClosePipe();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值