使用Windows命名管道,使用CreateNamedPipe
,ConnectNamedPipe
,DisconnectNamedPipe
和CloseHandle
来电的正确方法是什么?
我正在制作一个服务器应用程序,它连接到一个客户端应用程序,该应用程序在会话中多次连接和断开管道。
当我的写入因客户端断开而失败时,我应该拨打DisconnectNamedPipe
,CloseHandle
,或者我的手柄上没有任何内容。
然后,要接受新连接,我应该拨打CreateNamedPipe
然后ConnectNamedPipe
,还是ConnectNamedPipe
?
我非常希望通过这些调用来解释我的管道可能存在的不同状态,因为我没有在其他地方找到它。
其他信息:
语言:使用win32pipe
,win32file
和win32api
库的Python。
管道设置:WAIT,无重叠,字节流。
答案 0 :(得分:4)
优良作法是拨打DisconnectNamedPipe
然后CloseHandle
,尽管CloseHandle
应该清理所有内容。
MSDN文档有点模糊,server example非常基本。至于你是否重复使用管道把手,它似乎是你自己的选择。 DisconnectNamedPipe
的{{3}}似乎表明您可以在断开连接后再次在该句柄上调用ConnectNamedPipe
,以便为新客户端重新使用管道句柄。 ConnectNamedPipe
的作用似乎是将连接客户端分配给句柄。
尽管MSDN声明Documentation
,但请确保您正在清理管道每次创建命名管道时,系统都会使用非分页池创建入站和/或出站缓冲区,这是内核使用的物理内存。您可以创建的管道实例(以及线程和进程等对象)的数量受可用非页面缓冲池的限制。每个读取或写入请求都需要缓冲区中用于读取或写入数据的空间,以及内部数据结构的额外空间。
如果您正在创建/销毁大量管道,我也会考虑到上述情况。我猜想如果有很多客户端并且在池中有一些增长/收缩机制,那么操作一个管道句柄池会更好。
答案 1 :(得分:1)
我成功实现了我的目标。我每次会话只调用一次CreateNamedPipe
和CloseHandle
,当我的写入失败时,我会调用DisconnectNamedPipe
,然后是另一个ConnectNamedPipe
。
诀窍是只在实际连接管道时调用DisconnectNamedPipe
。每当我试图连接“只是为了确定”时我就打电话给它,它给了我奇怪的错误。
有关管道的更多信息,请参阅djgandy的答案。