1. ホーム
  2. python

[解決済み] python 3.6 ソケットの pickle データが切り捨てられた

2022-01-25 12:03:41

質問

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

私のクライアント 彼は私の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()

解決方法は?

の問題は、pickle data のサイズが > 4096 の場合、pickle data の最初の部分しか取得できないことです(そのため 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()

バイトオブジェクトを増やすのはあまり効率的ではなく、オブジェクトのリストにパーツを格納する方がよいでしょう。 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()