在Python 3.7中使用和重叠命名管道

问题描述 投票:1回答:1

我正在使用Windows与Python 3.7,我正在尝试异步共享数据,ony字符串,在python进程之间。其中一个是无限期运行(接收器),另一个可以在任何时刻开始发送一些数据然后结束(发送者)。我正在尝试使用命名管道。

当他们同步运行时,我设法得到了这个(接收器等待一个被阻塞的管道,直到他获得数据),然而接收器有其他的东西这样做,理想情况下他不应该一直等待。在某些时候可能还有第二个发送者,所以阻塞的管道不是很好。

接收器的代码是:

import os
import time
import sys
import win32pipe, win32file, pywintypes

pipe_name = r'\\.\pipe\mypipe' 

pipe = win32pipe.CreateNamedPipe(
        pipe_name,
        win32pipe.PIPE_ACCESS_DUPLEX | win32file.FILE_FLAG_OVERLAPPED,  # open mode 
        win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_READMODE_MESSAGE | win32pipe.PIPE_WAIT, # pipe mode
        1, 65536, 65536, # max instances, out buffer size,  in buffer size
        0, # timeout
    None)


while 1:
    print("doing my other stuff")
    try:
        win32pipe.ConnectNamedPipe(pipe, pywintypes.OVERLAPPED())
    except pywintypes.error as e:
        if e.winerror == 232:   #disconnected pipe
            win32pipe.DisconnectNamedPipe(pipe)
            print("Disconnecting pipe")
        else:
            print(e)
    try:
        retval, msg = win32file.ReadFile(pipe, 0, pywintypes.OVERLAPPED())
        print(msg)
    except pywintypes.error as e:
        if e.winerror == 536: #Wating for connection
            print("waiting")
        elif e.winerror == 233: #no process on other side
            continue
    time.sleep(1)

发件人的代码是:

import os
import time
import sys
import win32pipe, win32file, pywintypes


pipe_name = r'\\.\pipe\mypipe' 


for x in range(5):

    handle = win32file.CreateFile(
            pipe_name,
            win32file.GENERIC_READ | win32file.GENERIC_WRITE,
            0,
            None,
            win32file.OPEN_EXISTING,
            win32file.FILE_FLAG_OVERLAPPED,
            None
            )
    res = win32pipe.SetNamedPipeHandleState(handle, win32pipe.PIPE_READMODE_MESSAGE, None, None)
    print(f"sending {x}")
    win32file.WriteFile(handle, str.encode(f"hello world {x}"))
    win32file.CloseHandle(handle)
    time.sleep(2)

现在两者都可以运行并有一些连接,但我不能真正得到数据。接收器可以做任何事情并断开连接并重新打开管道,如果发送了什么,但msg最终是空的。如果我在调试器中停止它并发送一些东西,msg的值得到“内存在0x0 .......”,我将其解释为某种指针,但是当你probalby已经注意到我对管道的理解是有限的。

Here我找到了一个有效的同步管道的好例子。我将管道的创建改为接收器,但这并不难。我找到了异步(重叠)管道here的一些例子,它们也很棒,但让我知道我现在面临的问题。

我从重叠的管道读取仍然是win32file.ReadFileor的任务是他缺少的东西?

非常感谢你!

python pipe named-pipes overlapped-io
1个回答
0
投票

我找到了解决方案并希望分享它,以防万一其他人在这个问题上磕磕绊绊。事实证明msg得到“内存在0x0 .......”是一个memoryview对象,其数据可以通过bytes(msg)公开。

我的ReadFile命令也存在问题,因为缓冲区必须> 0才能实现任何目标。现在它分别读取每个字节并将它们添加到字符串中。这在性能方面可能不是很好,但它对我有用,并且它解决了如果消息短于缓冲区长度必须削减结束的问题。

msg = ''
rtnvalue, data = win32file.ReadFile(pipe, 1, pywintypes.OVERLAPPED())
while rtnvalue == 234:
    msg = msg + bytes(data).decode('ASCII') 
    rtnvalue, data = win32file.ReadFile(pipe, 1, pywintypes.OVERLAPPED())
if rtnvalue == 0: #end of stream is reached
    msg = msg + bytes(data).decode('ASCII')
return msg
© www.soinside.com 2019 - 2024. All rights reserved.