从 NamedPipeClientStream 调用命名管道时未连接
Posted
技术标签:
【中文标题】从 NamedPipeClientStream 调用命名管道时未连接【英文标题】:Named Pipe Not connecting when being called from NamedPipeClientStream 【发布时间】:2015-05-21 22:03:54 【问题描述】:在 IPC 代码中,如果我通过调用 CreateFile
使用 Win32 API 从命名管道获取句柄,一切正常。如果我使用NamedPipeClientStream
做同样的事情,它不想连接。
工作版
[DllImport("kernel32.dll")]
internal static extern SafePipeHandle CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr securityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile);
public openPipe()
SafePipeHandle localDeviceHandle;
// Second Paameter is READ/WRITE Access, Fifth Parameter Open Existing
// This was done for brevity of the example.
localDeviceHandle = FileApi.CreateFile("\\\\.\\SeaMAC0",
(uint)3,
0,
IntPtr.Zero,
(uint)3,
(uint)FileApi.FileAttribute.Normal,
IntPtr.Zero);
不工作
public openPipe()
SeaLevelNamedPipe = new NamedPipeClientStream("SeaMAC0");
/*or SeaLevelNamedPipe = new NamedPipeClientStream(".","SeaMAC0");*/
SeaLevelNamedPipe.Connect(); //It will hang here for ever
这里的代码远未完成,为简洁起见。它们的功能不应该一样吗?
我无权访问服务器管道代码,因为这是由第三方开发的。
【问题讨论】:
【参考方案1】:在您的第一个“this works”示例中,您没有为 lpFileName
参数使用有效的命名管道名称。这:"\\\\.\\SeaMAC0"
不是有效的命名管道名称。
参考documentation on Pipe Names:
在
CreateFile
、WaitNamedPipe
或CallNamedPipe
函数中指定管道名称时使用以下形式:\\ServerName\pipe\PipeName
其中
ServerName
是远程计算机的名称或句点,用于指定本地计算机。PipeName
指定的管道名称字符串可以包含除反斜杠以外的任何字符,包括数字和特殊字符。整个管道名称字符串最长可达 256 个字符。管道名称不区分大小写。管道服务器无法在另一台计算机上创建管道,因此
CreateNamedPipe
必须使用句点作为服务器名称,如下例所示。\\.\pipe\PipeName
因此,在您的第二个“不起作用”示例中,.NET NamedPipeClientStream
将用于连接到服务器管道的构造管道名称是:
\\.\pipe\SeaMAC0
随后在调用WaitNamedPipe
Win32 方法时使用它来尝试连接到命名管道服务器,在连接循环中,当调用Connect
时无限超时。鉴于不存在具有给定名称的管道服务器这一事实,它将完全按照您的描述结束:等待,永远孤独。
请注意,对于您使用的文件名 ("\\\\.\\SeaMAC0"
):
Win32 Device Namespaces
"\\.\"
前缀将访问 Win32 设备命名空间,而不是 Win32 文件命名空间。...
如果您使用的是 Windows API 函数,则应使用
"\\.\"
前缀仅访问设备而非文件。
例如\\.\COM1
将打开 COM1 设备的句柄,\\.\DISPLAY1
代表默认显示设备。如果SeaMAC0
不是您系统上的实际设备名称,则您的“工作版本”可能返回一个无效的句柄。如果这样的设备确实存在,它会返回设备的句柄,而不是命名管道实例。
【讨论】:
实际上它是一个设备sealevel.com/store/serial/synchronous-serial/pci-express/… 它是一个同步串行卡。但是感谢您提供的链接,它将让我有机会阅读更多关于此的内容。 @56K 看来这些信息与您的问题非常相关。您可能想要编辑它并添加信息。这也意味着这个答案仍然解释了为什么你会看到你观察到的行为。我会更新答案以纳入您的新信息。以上是关于从 NamedPipeClientStream 调用命名管道时未连接的主要内容,如果未能解决你的问题,请参考以下文章
NamedPipeServerStream/NamedPipeClientStream 包装器
NamedPipeClientStream - 服务器断开连接时的通知
异步使用 NamedPipeServerStream 和 NamedPipeClientStream
NamedPipeClientStream 在应用服务中不起作用
关闭 NamedPipeClientStream 时出现 System.Net.Sockets.SocketException