命名管道实战

管道命名要求

lpName (ref msdn)
The unique pipe name. This string must have the following form:
\.\pipe\pipename

#define PIPENAME_TEST _T("\\\\.\\pipe\\test")

命名管道服务

官网demo,可能存在时机问题,导致WaitNamedPipe失败。优化代码如下:

DWORD WINAPI _pip_server(LPVOID lparam)
{
	HANDLE hPipe = CreateNamedPipe(PIPENAME_TEST, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUFF_SIZE, BUFF_SIZE, 0, NULL);
	DWORD dwErrorCode = 0;
	if (hPipe == INVALID_HANDLE_VALUE)
	{
		dwErrorCode = GetLastError();
		printf("CreatePipeServe failed:%d\r\n", dwErrorCode);
		return 0;
	}

	while (true)
	{
		BOOL bRes = ConnectNamedPipe(hPipe, NULL) ? TRUE : (dwErrorCode = GetLastError() == ERROR_PIPE_CONNECTED);
		if (bRes)
		{
			DWORD dwReaded = 0;
			char tmpBuffer[BUFF_SIZE] = { 0 };
			DWORD dwErrorCode = 0;
			string strRes = "";
			bool bContinue = false;
			do
			{
				bContinue = false;
				dwReaded = 0;
				memset(tmpBuffer, 0, BUFF_SIZE);
				if (!ReadFile(hPipe, tmpBuffer, BUFF_SIZE, &dwReaded, NULL))
				{
					dwErrorCode = GetLastError();
					if (dwErrorCode == ERROR_MORE_DATA)
					{
						if (dwReaded) strRes.append(tmpBuffer, dwReaded);
						bContinue = true;
					}
					else
					{
						printf("Server ReadFile failed:%d", dwErrorCode);
						break;
					}
				}
				else
				{
					if (dwReaded) strRes.append(tmpBuffer, dwReaded);
					break;
				}
			} while (bContinue);
			DisconnectNamedPipe(hPipe);

			//投递到任务队列
			//postTask(strRes)
		}
		
	}
	CloseHandle(hPipe);
}
关闭Pipe服务
#如果N个线程_pip_server,则需要关闭N次
void stop()
{
	_log_fmt("CPipeServer::stop ing");
	for (int i = 0; i < m_nlisten_number; ++i)
	{
		::DeleteFileA(m_str_pipe_name.c_str());
	}
	#这里不能通过CloseHandle(hpipe)通知结束,如果此时线程正在操作pipe,
	#例如wait,connect等,则CloseHandle将会阻塞等操作结束才能返回
	#关闭管道之后,记得Wait线程退出
}
命名管道客户端
HANDLE ConnectToServer( int nTimeOut )
{
	HANDLE hPipe = NULL;
	while (1) 
	{
		hPipe = CreateFileA(PIPENAME_TEST.c_str(),GENERIC_READ |GENERIC_WRITE, 0, NULL,OPEN_EXISTING,0,NULL);
		if (hPipe != INVALID_HANDLE_VALUE) break; 
		DWORD dwErrorCode = GetLastError();
		printf("Could not open pipe ErrorCode:%d", dwErrorCode);
		if (dwErrorCode != ERROR_PIPE_BUSY) 
			return NULL;

		if (!WaitNamedPipeA(m_strPipeName.c_str(), nTimeOut))
		{
			dwErrorCode = GetLastError();
			printf("Could not open pipe In Time ErrorCode:%d", dwErrorCode);
			return NULL;
		} 
	}
	return hPipe;
}

bool PostPipeReuest(string szJsonCmd )
{
	bool bret = false;
	if (szJsonCmd.empty()) return bret;
	HANDLE hPipe = ConnectToServer(-1);
	if (!hPipe) return bret;
	int nSize = szJsonCmd.length()+1;
	char *buffer = new char[nSize];
	sprintf_s(buffer,nSize,"%s",szJsonCmd.c_str());
	buffer[nSize-1] = '\0';
	DWORD dwWrited = 0;
	BOOL bRes = WriteFile(hPipe,buffer,nSize,&dwWrited,NULL);
	if (!bRes) 
	{
		DWORD dwErrorCode = GetLastError();
		printf("PostReuest WriteFile failed:%d", dwErrorCode);
	}
	else if(dwWrited != nSize)
	{
		bret = true;
		printf("SendRequest WriteFile Incomplete");
	}
	delete[] buffer;
	buffer = NULL;
	CloseHandle(hPipe); 
	return bret;
}


你可能感兴趣的:(C++,随笔,管道,命名管道,pipe)