我有一个日志记录工具(SS_Log的后代),它由一个独立的日志查看器和一个C ++ lib组成,用于通过命名管道发送消息。
当记录第一条消息时,客户端通过C ++ lib启动日志查看器,并且
HANDLE hPipe = CreateNamedPipe( szPipeName,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE|PIPE_WAIT|PIPE_READMODE_MESSAGE,
PIPE_UNLIMITED_INSTANCES,
SSLOG_MAX_MESSAGE_LENGTH,
0, 5000, &sa );
pView->Pipe(hPipe);
if( pView->Pipe() == INVALID_HANDLE_VALUE )
{
pView->MessageBox( _T("Could not create the pipe for incoming messages. No messages can be received. "),
_T("Fatal Error"), MB_OK|MB_ICONSTOP );
return FALSE;
}
// now we loop forever, waiting for messages. As they come in, send them
// to the SS_Log_WindowView::EraseLog() and SS_Log_WindowView::WriteLog()
// functions as appropriate.
while( TRUE )
{
ConnectNamedPipe( pView->Pipe(), NULL );
...
}
当客户想要发送消息时,它会
BOOL bResult = WaitNamedPipe(WindowPipeName(), 20000);
bResult = CallNamedPipe(WindowPipeName(), (LPVOID)szFinalBuffer,
_tcslen(szFinalBuffer)+1, (LPVOID)NULL,
0, &dwBytesRead,
5000);
我想获得一个与这个命名管道相对应的HANDLE。文档建议我可以使用CreateFile( WindowPipeName(), GENERIC_READ|GENERIC_WRITE,...OPEN_EXISTING,...)
创建一个。当我这样做时,一些东西显然开始阻塞,日志查看器不再收到任何消息。甚至没有用那个HANDLE做任何事情。
是否有可能做我想要的,如果可以,怎么做?
答案 0 :(得分:1)
日志查看器的循环以调用ConnectNamedPipe
开始。所以它等待客户端连接,读取消息,返回到循环的顶部并等待客户端再次连接。
这适用于CallNamedPipe
,因为该函数每次发送消息时都会连接和断开连接。
但是如果客户端通过使用CreateFile
打开管道句柄来创建持久连接,那么它只连接一次。在服务器中,对ConnectNamedPipe
的第二次调用将挂起,等待另一个客户端连接。
如果您希望日志查看器仅处理具有持久连接的单个客户端,则可以使用一个循环来调用ConnectNamedPipe
,然后使用内部循环来处理来自客户端的消息,直到管道关闭为止。
如果您想处理多个客户端,那么您当前的解决方案比尝试处理多个同时连接要简单得多。