tcp - - 无效的加载键,ZMQ socket.recv_pyobj() 中的 '\x00'
问题描述
我已参考相关查询,无法修复上述错误。我正在两个单独的进程之间运行服务器和客户端 python 对象共享。客户端需要将字典或元组发送到服务器。我尝试将协议更改为 pickle.DEFAULT_PROTOCOL 和 pickle.HIGHEST_PROTOCOL。问题仍然没有解决......但是可以打印我发送的字典。
服务器代码:
import zmq
import socket
import sys
import datetime
import pickle
def errorhandling(name: str, msg: str) -> None:
"""
To handle Error in the API and Strategies, if you call this
"""
try:
print(f" {datetime.datetime.now().time()}| ERROR |{name} | {msg} | {sys.exc_info()[0]} -"
f" {sys.exc_info()[1]} | Line No:{sys.exc_info()[2].tb_lineno}")
except Exception as e:
print("error", f" {name} | ErrorHandlingError - {e}")
ip = socket.gethostbyname(socket.gethostname())
ordcontext = zmq.Context()
ordsocket = ordcontext.socket(zmq.XREP)
ordsocket.bind(f"tcp://{ip}:7712")
def ordersocket():
print("Order socket Running")
while True:
try:
#orddata = self.ordsocket.recv().decode('utf-8', 'ignore')
orddata = ordsocket.recv_pyobj()
#orddata2 = pickle.loads(orddata)
print(orddata)
except Exception:
errorhandling(name="ordername",
msg="ordersocket")
print("Order socket NOT Running")
ordersocket()
客户代码:
import zmq
import time
import socket
import pickle
ip = socket.gethostbyname(socket.gethostname())
orcontext = zmq.Context()
orsocket = orcontext.socket(zmq.XREQ)
orsocket.connect(f"tcp://{ip}:7712")
def sendorder():
while True:
data = {"A": "Nameofstg", "LTP": 1200, "QTY":200, "SS":"Now", "PP":230}
orsocket.send_pyobj(obj=data,protocol=pickle.HIGHEST_PROTOCOL)
time.sleep(3)
sendorder()
错误(带有打印语句):
<class '_pickle.UnpicklingError'> - invalid load key, '\x00'.
11:34:49.665037| 错误 |订单名称 | 订单套接字 | <class '_pickle.UnpicklingError'> - 无效的加载键,'\x00'。| 行号:35 {'A': 'Nameofstg', 'LTP': 1200, 'QTY': 200, 'SS': 'Now', 'PP': 230}
解决方案
我不确定你的代码有什么问题,但试试下面的代码,它可以工作。你其实不需要pickle
,socket.send_pyobj
可以用来像字典一样发送对象。
假设master.py
和worker.py
下同dir
。
master.py
import zmq
import sys
import pexpect
from getpass import getuser
from socket import gethostname
python = sys.executable
context = zmq.Context()
socket = context.socket(zmq.REP)
port = socket.bind_to_random_port("tcp://*")
server_host = gethostname()
server_socket = "%s:%s" % (server_host, port)
worker_command = "%s -m worker" % python + " %i " + server_socket
children = []
for ind in range(4):
child = pexpect.spawn(worker_command % ind)
children.append(child)
active = 4
while True:
message = socket.recv_pyobj()
print(message)
socket.send_pyobj('task done')
active -= 1
if active == 0:
break
和worker.py
import os
import sys
import zmq
from socket import gethostname
if __name__ == '__main__':
import logging
logging.basicConfig(filename = f"log")
try:
server_socket = sys.argv[-1]
worker_id = int(sys.argv[-2])
port_number = int(server_socket.split(':')[-1])
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect('tcp://%s' % server_socket)
data = {"A": "Nameofstg_%i" % worker_id}
socket.send_pyobj(data)
socket.recv_pyobj()
except Exception as e:
logging.exception(e)
运行可以看到,python master.py
四个worker发送的字典都可以被master成功接收到,其实你不需要,pickle
因为我们使用socket.send_pyobj
.
您可能还注意到,在 中worker.py
,我使用logging.basicConfig(filename = f"log")
. 这样做,Exception
可以捕获工作进程中的 。
推荐阅读
- algorithm - 选择 Waves 的光盘视图中的 Matalb 代码错误
- python - 达到特定倍数后从范围中获取下一个值
- .htaccess - ht-access 如何重定向到论坛主题网址?
- python - 如何在 Kivy 中固定小部件?(或窗户)
- python - Python Naive Bayes 训练问题 - cannoy 使用灵活类型执行 reduce
- c++ - 创建具有构造函数中给定大小的数组
- python - 为 python 代码使用 HTML 表单输入并在 HTML 网页中获取输出
- json - 过滤没有数据的 json 子项
- c++ - 将数组元素插入哈希表
- python - Django租户模式“argparse.ArgumentError:参数--skip-checks:冲突的选项字符串:--skip-checks”