如何解决<class'_pickle.UnpicklingError'>-无效的加载密钥,ZMQ socket中的'\ x00'.recv_pyobj
我已提及相关查询,但无法解决上述错误。我正在两个单独的进程之间运行服务器和客户端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 |错误|订单名|订购单|
解决方法
我不确定您的代码中有什么问题,但是请尝试下面的代码,它可以工作。您实际上不需要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
可以看到,主服务器可以成功接收四个工作人员发送的词典,实际上,您不需要pickle
,因为我们使用{{1} }。
您可能还注意到,在socket.send_pyobj
中,我使用worker.py
。这样做可以捕获工作进程中的logging.basicConfig(filename = f"log")
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。