web-dev-qa-db-fra.com

python 3,6 données de pickle de socket ont été tronquées

je ne peux pas envoyer mon tableau numpy dans le socket, j'utilise cornichon mais il mon crash de cornichon client avec cette erreur: les données de cornichon ont été tronquées

mon serveur: je crée un tableau numpy et je veux envoyer mon client avec cornichon (ça marche)

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()

mon client Il a mon tableau numpy, mais je ne peux pas charger avec des cornichons, j'ai cette erreur.

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()
8
sazearte

le problème est que si la taille des données marinées est> 4096, vous obtenez uniquement la première partie des données marinées (d'où le pickle data was truncated message que vous recevez)

Vous devez ajouter les données et les décaper uniquement lorsque la réception est terminée, par exemple comme ceci:

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

data_arr = pickle.loads(data)
print (data_arr)
s.close()

augmenter un octet n'est pas très performant, il serait préférable de stocker les pièces dans une liste d'objets, puis join. Variante plus rapide:

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()
6