将 ipc:// 更改为 tcp:// 在 Python zmq(Windows)中

5 投票
1 回答
3933 浏览
提问于 2025-05-01 06:53

我正在尝试在Windows上运行一个Python应用程序,但遇到了一个错误:ZMQError: Protocol not supported。这是因为Windows不支持ipc(进程间通信)。

根据我所了解,把ipc换成tcp协议应该很简单,只需要在bind()函数中更改字符串就可以了。

        master_addr = 'ipc://{0}/sailfish-master-{1}_{2}'.format(
                tempfile.gettempdir(), os.getpid(), subdomain.id)
        ipc_files.append(master_addr.replace('ipc://', ''))
        sock = ctx.socket(zmq.PAIR)
        sock.bind(master_addr)
        sockets.append(sock) 

但是如果我把ipc://改成tcp://,就会出现ZMQError: Invalid argument的错误,所以我想这可能没有那么简单。

你能帮我一步步解决这个在Windows上的问题吗?或者告诉我我是不是在问一个愚蠢的问题。

你可以查看完整的脚本,链接在这里:https://github.com/sailfish-team/sailfish/blob/master/sailfish/master.py,上面的代码来自第250行。

SailfishCFD是一个用于GPU(CUDA,OpenCL)的Python格子玻尔兹曼(LBM)模拟包。

非常感谢!

暂无标签

1 个回答

9

ZeroMQ是与传输方式无关的

这意味着,无论使用什么传输方式,比如 { inproc:// | ipc:// | tcp:// | pgm:// | epgm:// },都可以发送消息。

但这并不意味着在不同的情况下,使用的地址格式是一样的。

master_addr = 'ipc://{0}/sailfish-master-{1}_{2}'.format( tempfile.gettempdir(),
                                                          os.getpid(),
                                                          subdomain.id
                                                          )
sock.bind( master_addr )                                  # works on Linux/ipc
#   .bind( <<<tcp_addr>>> )                               # fails on "{0}{1}{2}".format-addressing"

在Windows系统上,不能使用 ipc: 这种传输方式。这种需要更改的情况会影响到你代码的范围,因为在地址处理上有一些额外的关于ipc的假设。

如下面所示:

addr         = "tcp://{0}".format( self._subdomain_addr_map[nbid] ) # tcp://<ip>:<port>?
addr         = "tcp://{0}".format( self._iface )                    # ref. #104 missing ":<port>" part!
summary_addr = 'tcp://127.0.0.1:{0}'.format( config._zmq_port )     # port free?

首先要做的是:

明确问题。你的代码使用类似“fileName”的命名方式来处理IPC管道。你可以从这里开始。

try:
     print                                   "DEBUG: Try to .bind() a ", master_addr
     sock.bind( master_addr )
     print                                   "     ==OK."

except ZMQError as Exc:
     print                                   "     ! FAILED:"
     # log & handle Exc details

except:
     print                                   "     ! FAILED: a non-ZMQ-related issue"
     # log & handle Exc details

端口号:

确保在Windows上使用 zmq.bind() 时,不要去碰那些“受限”的、已经“被使用”的或“被防火墙阻挡”的TCP端口号。

检查这些系统设置后,确保你的zmq调用语法与ZeroMQ API的tcp://传输方式兼容,

也就是说:

"tcp://<ip_address>:<port#>" # 作为字符串

或者

"tcp://<aDnsResolvableHostNAME>:<port#>" # 作为字符串

这样就可以了。

撰写回答