python 命名管道_Python和Windows命名管道

What is the proper way of communicating with named pipes on Windows from Python? I've googled it, and can't find any packages that wrap this communication.

There are:

some descriptions of how to do it with pywin32 (I could not find how to connect to an existing pipe with it, though).

This package: https://pypi.python.org/pypi/PyWPipe/ (had no luck with it either)

I need just to connect to an existing named pipe and read/write to it. I previously had only tried communication with serial port (using pySerial), and I'm surprised how little info I could find on named pipes in comparison to it. There's usually tons of guides for any purpose for Python.

I'll appreciate any help.

解决方案

In order to connect to an existing named pipe you can utilize the CreateFile API provided through the pywin32 package. Since it took me a while to put a working base together here is an example client/server which works fine for me (python 3.6.5, pywin32 223 on Windows 10 Pro x64):

import time

import sys

import win32pipe, win32file, pywintypes

def pipe_server():

print("pipe server")

count = 0

pipe = win32pipe.CreateNamedPipe(

r'\\.\pipe\Foo',

win32pipe.PIPE_ACCESS_DUPLEX,

win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_READMODE_MESSAGE | win32pipe.PIPE_WAIT,

1, 65536, 65536,

0,

None)

try:

print("waiting for client")

win32pipe.ConnectNamedPipe(pipe, None)

print("got client")

while count < 10:

print(f"writing message {count}")

# convert to bytes

some_data = str.encode(f"{count}")

win32file.WriteFile(pipe, some_data)

time.sleep(1)

count += 1

print("finished now")

finally:

win32file.CloseHandle(pipe)

def pipe_client():

print("pipe client")

quit = False

while not quit:

try:

handle = win32file.CreateFile(

r'\\.\pipe\Foo',

win32file.GENERIC_READ | win32file.GENERIC_WRITE,

0,

None,

win32file.OPEN_EXISTING,

0,

None

)

res = win32pipe.SetNamedPipeHandleState(handle, win32pipe.PIPE_READMODE_MESSAGE, None, None)

if res == 0:

print(f"SetNamedPipeHandleState return code: {res}")

while True:

resp = win32file.ReadFile(handle, 64*1024)

print(f"message: {resp}")

except pywintypes.error as e:

if e.args[0] == 2:

print("no pipe, trying again in a sec")

time.sleep(1)

elif e.args[0] == 109:

print("broken pipe, bye bye")

quit = True

if __name__ == '__main__':

if len(sys.argv) < 2:

print("need s or c as argument")

elif sys.argv[1] == "s":

pipe_server()

elif sys.argv[1] == "c":

pipe_client()

else:

print(f"no can do: {sys.argv[1]}")

Example output client

> python pipe_test.py c

pipe client

no pipe, trying again in a sec

no pipe, trying again in a sec

no pipe, trying again in a sec

message: (0, b'0')

message: (0, b'1')

message: (0, b'2')

message: (0, b'3')

message: (0, b'4')

message: (0, b'5')

message: (0, b'6')

message: (0, b'7')

message: (0, b'8')

message: (0, b'9')

broken pipe, bye bye

Example output server

> python pipe_test.py s

pipe server

waiting for client

got client

writing message 0

writing message 1

writing message 2

writing message 3

writing message 4

writing message 5

writing message 6

writing message 7

writing message 8

writing message 9

finished now

Obviously you'd need some error checking around the various calls but that should work.

Additional side note: A colleague of mine ran into trouble with the pipe being closed the moment the client tried to perform I/O on it (exception claiming that "all pipe instances are busy"). It turned out that he was using os.path.exists in the client code to test whether the named pipe already existed before running CreateFile on it. This somehow breaks the pipe. So using the approach above (CreateFile wrapped in a try-except) is the safe way of trying to connect to a pipe until it has been created by the server end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值