【问题标题】:Windows pipes: Write from C - read in PythonWindows 管道:从 C 写入 - 在 Python 中读取
【发布时间】:2016-01-17 06:01:07
【问题描述】:

我想通过管道传输几个字节的数据以从 python 中绘制它。

我从在这里找到的一些 sn-ps 开始,但我无法让它们工作。

我已经创建了这样的管道:

int main(void){

HANDLE hPipe;
char buffer[24];
DWORD dwRead;


hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\Pipe"),
                        PIPE_ACCESS_DUPLEX | PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,   // FILE_FLAG_FIRST_PIPE_INSTANCE is not needed but forces CreateNamedPipe(..) to fail if the pipe already exists...
                        PIPE_WAIT,
                        1,
                        24 * 16,
                        24 * 16,
                        NMPWAIT_USE_DEFAULT_WAIT,
                        NULL);


while (hPipe != INVALID_HANDLE_VALUE)
{
    if (ConnectNamedPipe(hPipe, NULL) != FALSE)   // wait for someone to connect to the pipe
    {
        while (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &dwRead, NULL) != FALSE)
        {
            /* add terminating zero */
            buffer[dwRead] = '\0';

            /* do something with data in buffer */
            printf("%s", buffer);
        }
    }

    DisconnectNamedPipe(hPipe);
}

return 0;}

如果我执行以下代码,它会写入但读取部分会阻塞:

  import time
  import struct

  f = open(r'\\.\\pipe\\Pipe', 'r+b', 0)
  i = 1
  sss='ccccc'
  while True:

   s = sss.format(i)
   i += 1

   f.write(struct.pack('I', len(s)) + s)   # Write str length and str
   f.seek(0)                               # EDIT: This is also necessary
   print 'Wrote:', s

   n = struct.unpack('I', f.read(4))[0]    # Read str length
   s = f.read(n)                           # Read str
   f.seek(0)                               # Important!!!
   print 'Read:', s
   time.sleep(2)

我尝试在 C 代码中注释 ReadFile 部分,但它不起作用。有没有其他方法可以实现这一目标?我想用 C 编写并从 python 读取。我尝试使用 CreateFile(来自 C)写入管道,它按预期工作。我只需要用 python 读取部分。

【问题讨论】:

  • 管道是向前移动的数据流——您不能向后搜索到流的开头。
  • “r+b”(在尝试写入之前打开“f”的模式)在 Python 中是什么意思?
  • 在大多数系统上,管道是单向连接。一个对象在写,另一个在读。如果您需要双向连接,则需要两条管道。在 python 示例中,您必须打开管道两次 - 一个用于读取,另一个用于写入。
  • seek() 在将双向文件描述符从读取更改为写入时需要,(通常使用相对搜索,seek(0,1))但由于 Windows 命名管道不是基于文件描述符的,它可能不会不要做任何有用的事情。或者可能只是 seek(0) 不起作用。
  • 这个问题的标题是write from C, read from python所以要么标题不正确要么C代码做错了,因为C代码是reading管道,而不是writing管道。

标签: python c pipe named-pipes


【解决方案1】:

在大多数系统上,管道是单向的,您使用两个管道来获得双向(双向)连接。

在您的 Python 代码中,您可以打开两个连接 然后你就不需要seek

import time
import struct

wf = open(r'Pipe', 'wb', 0)
rf = open(r'Pipe', 'rb', 0)

i = 0
template = 'Hello World {}'

while True:

   i += 1
   text = template.format(i)

   # write text length and text
   wf.write(struct.pack('I', len(text))) 
   wf.write(text)   
   print 'Wrote:', text

   # read text length and text
   n = struct.unpack('I', rf.read(4))[0]
   read = rf.read(n)
   print 'Read:', read

   time.sleep(2)

编辑:在 Linux Mint 17、Python 3.4 和 2.7 上测试

【讨论】:

  • 我无法让它工作。我可以打开管道进行写入或读取,但不能同时打开。每当我尝试打开第二个管道时,它都会显示“IOError:[Errno 22] 无效模式或文件名:'\\\\.\\\\pipe\\\\Pipe'”。
  • 我使用 Linux 并且它可以工作 - 也许在其他系统上存在一些问题。我必须先打开“写”,因为它会创建管道。
  • 是的,它在 linux 上有效,但我需要使用 windows 管道。还是谢谢。
【解决方案2】:

我已经用 PyWin32(http://sourceforge.net/projects/pywin32/files/) 解决了这个问题,这似乎是 Windows 的正确工具。我宁愿使用更面向跨平台的东西,但它已经解决了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多