python 3.6套接字pickle数据被截断

saz*_*rte 8 python sockets pickle

我无法在插座中发送我的numpy数组,我使用pickle但是我的客户端pickle因此错误而崩溃:pickle数据被截断

我的服务器:我创建numpy数组,我想在我的客户端发送pickle(这是工作)

import socket, pickle
import numpy as np
from PIL import ImageGrab
import cv2


while(True):
    HOST = 'localhost'
    PORT = 50007
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 4096)
    s.bind((HOST, PORT))
    s.listen(1)
    conn, addr = s.accept()
    print ('Connected by', addr)

    arr = np.array([[0, 1], [2, 3]])
    printscreen_pil=ImageGrab.grab(bbox=(10,10,500,500))
    img = np.array(printscreen_pil) ## Transform to Array

    data_string = pickle.dumps(img)
    conn.send(data_string)

    msg_recu = conn.recv(4096)
    print(msg_recu.decode())

    conn.close()
Run Code Online (Sandbox Code Playgroud)

我的客户他有我的numpy数组,但我无法加载pickle,我有这个错误.

import socket, pickle
import numpy as np

HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))

msg_a_envoyer = "hello".encode()
s.send(msg_a_envoyer)


while 1:
    data = s.recv(4096)
    if not data: break
    data_arr = pickle.loads(data)
    print (data_arr)
s.close()
Run Code Online (Sandbox Code Playgroud)

Jea*_*bre 6

问题是如果腌制数据的大小> 4096,你只得到腌制数据的第一部分(因此pickle data was truncated你得到的消息)

您必须附加数据并仅在接收完成时将其腌制,例如:

data = b""
while True:
    packet = s.recv(4096)
    if not packet: break
    data += packet

data_arr = pickle.loads(data)
print (data_arr)
s.close()
Run Code Online (Sandbox Code Playgroud)

join然而,增加一个字节对象的性能不是很好,最好将这些部分存储在一个对象列表中.更快的变体:

data = []
while True:
    packet = s.recv(4096)
    if not packet: break
    data.append(packet)
data_arr = pickle.loads(b"".join(data))
print (data_arr)
s.close()
Run Code Online (Sandbox Code Playgroud)


Cre*_*ost 6

简而言之,您尝试加载的文件不完整。要么您没有正确下载它,要么只是您的 pickle 文件已损坏。您可以创建一个新的pickle来解决这个问题