Windows命名管道不能正确响应并发请求
本文关键字:响应 并发 请求 不能 管道 Windows | 更新日期: 2023-09-27 18:17:54
我使用命名管道在一个程序内部进行通信(在Windows XP上)。当我连接2-3个客户端时,命名管道可以很好地用于多个连接。然而,当我同时应用几个连接时(例如10),只有少数连接可以被ConnectNamedPipe()接受,通信似乎被卡住了。
但是当我在客户端代码中调试时,我发现所有客户端CreateFile函数都正确返回了文件句柄(似乎是正确的)。这是令人困惑的,因为我看到CreateNamedPipe循环,它只创建了大约一半的句柄…
服务器部分: while (!isPipeServerClosed)
{
try
{
filehandle = CreateNamedPipe(
this.pipeName,
DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
255,
InBufferSize,
InBufferSize,
0,
IntPtr.Zero);
if (ConnectNamedPipe(filehandle, IntPtr.Zero) > 0)
{
PipeThread pipe = new PipeThread(filehandle);
sPipeThreadList.Add(pipe);
}
}
catch (Exception exp)
{
System.Console.WriteLine(exp.StackTrace);
}
}
客户端部分,简单的Delphi代码(行为相同,即使我尝试与WaitNamedPipe):
FHandle := INVALID_HANDLE_VALUE;
FHandle := CreateFile(PChar(FPipeName),GENERIC_READ or GENERIC_WRITE,
0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
// create the class
if FHandle = INVALID_HANDLE_VALUE then
begin
Connected := false;
end
我能知道我错过了什么吗?谢谢你!
您没有正确使用重叠操作。特别是:
如果以FILE_FLAG_OVERLAPPED打开hNamedPipe,则loverlapped参数不能为NULL。它必须指向一个有效的OVERLAPPED结构。如果hNamedPipe用FILE_FLAG_OVERLAPPED和为NULL时,该函数可能错误地报告连接操作完成。
也,我想象有时您的ConnectNamedPipe
调用将返回错误,因为客户端尚未连接(ERROR_IO_PENDING)。在这些情况下,当连接完成时,您的客户端将成为"孤儿",因为您没有为它们创建PipeThread
。
如果你想使用重叠模式,你应该做更多的研究并正确地实现它。或者,如果你从CreateNamedPipe的参数中删除FILE_FLAG_OVERLAPPED,那么ConnectNamedPipe将阻塞,直到客户端已经连接,这个问题不会发生,尽管你会有一个不同的问题:当你想要停止服务器时如何解除阻塞(你会在这里找到一些答案,IIRC)。