使用套接字和python时获取pickle数据截断错误 [英] Getting pickle data truncated error while working with sockets and python

查看:63
本文介绍了使用套接字和python时获取pickle数据截断错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题来了.我试图通过套接字发送大量二进制图像代码,这是 OpenCV 图像的腌制数据.我正在调整图像大小,然后将其从服务器发送到客户端.当我将图像大小调整为 (160,120) 时,我没有收到错误,但在将调整大小设置为 (640,480) 时收到错误.我需要解决这个错误.请帮忙.

so here the problem. I am trying to send a large amount of binary image code over sockets which is the pickled data of the OpenCV image. I am resizing my image and then sending it from the server to the client. I am not getting an error when I am resizing the image to (160,120) but getting an error when the resize is set to (640,480). I need to solve this error. please help.

我的 server.py

my server.py

import socket, cv2, pickle, struct

# Socket Create
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host_name = socket.gethostname()
host_ip = socket.gethostbyname(host_name)
print('HOST IP:', host_ip)
port = 9999
socket_address = (host_ip, port)

# Socket Bind
server_socket.bind(socket_address)

# Socket Listen
server_socket.listen(5)
print("LISTENING AT:", socket_address)
Header_length = 20

# Socket Accept
while True:
    client_socket, addr = server_socket.accept()
    print('GOT CONNECTION FROM:', addr)
    if client_socket:
        vid = cv2.VideoCapture(0)

        while (vid.isOpened()):
            img, frame = vid.read()
            resized_frame = cv2.resize(frame , (640,480))
            a = pickle.dumps(resized_frame)
            message = f"{len(a):<{Header_length}}".encode('utf-8') + a
            client_socket.sendall(message)

            cv2.imshow('TRANSMITTING VIDEO', frame)
            key = cv2.waitKey(1) & 0xFF
            if key == ord('q'):
                client_socket.close()

我的客户端.py

import socket, cv2, pickle, struct

# create socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host_name = socket.gethostname()
host_ip = socket.gethostbyname(host_name)  # paste your server ip address here
port = 9999
client_socket.connect((host_ip, port))  # a tuple
data = b""
payload_size = struct.calcsize("Q")
while True:
    recieved_data = client_socket.recv(20).decode('utf-8')
    if not recieved_data:
        continue
    frame_data = client_socket.recv(int(recieved_data))
    frame = pickle.loads(frame_data)
    cv2.imshow("RECEIVING VIDEO", frame)
    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        break
client_socket.close()

如果您需要更多信息,请引理.

please lemma know if you want any more info.

推荐答案

.recv(n) 接收最多 n 个字节的数据,但可能(并且可能会)少回来.检查接收到的 frame_data 的长度,如果小于 n,则为余数发出另一个 .recv,直到获得所有字节.

.recv(n) receives upto n bytes of data, but may (and likely will) return less. Check the length of frame_data received and if less than n issue another .recv for the remainder, until you have all the bytes.

还要查看 socket.makefile 将套接字包装在一个类似文件的对象中,您可以调用 .read(n) 来准确读取 n 个字节.

Also look into socket.makefile which wraps the socket in a file-like object, and you can call .read(n) to read exactly n bytes.

客户端/服务器之间对象的两种方式酸洗的完整示例:

Full-example of two way pickling of objects between client/server:

from socket import *
import threading
import pickle

class ObjectStream:

    def __init__(self, sock):
        self.sock = sock
        self.writer = sock.makefile('wb')
        self.reader = sock.makefile('rb')
            
    # Objects are sent/received as a 4-byte big-endian integer of
    # the pickled object data length, followed by the pickled data.

    def get_obj(self):
        header = self.reader.read(4)
        if not header:
            return None
        length = int.from_bytes(header,'big')
        return pickle.loads(self.reader.read(length))

    def put_obj(self,obj):
        data = pickle.dumps(obj)
        header = len(data).to_bytes(4,'big')
        self.writer.write(header)
        self.writer.write(data)
        self.writer.flush()  # important!

    def close(self):
        if self.sock is not None:
            self.writer.close()
            self.reader.close()
            self.sock.close()
            self.sock = None
            self.writer = None
            self.reader = None

    # Support for 'with' to close everything.

    def __enter__(self):
        return self
    
    def __exit__(self,*args):
        self.close()

    # Support for no more references to ObjectStream

    def __del__(self):
        self.close()

def server():
    s = socket()
    s.bind(('',9999))
    s.listen()
    with s:
        while run:
            c,a = s.accept()
            print('server: connect from',a)
            with ObjectStream(c) as stream:
                while True:
                    obj = stream.get_obj()
                    print('server:',obj)
                    if obj is None: break
                    if isinstance(obj,list):
                        # reverse lists
                        stream.put_obj(obj[::-1])
                    elif isinstance(obj,dict):
                        # swap key/value in dictionaries
                        stream.put_obj({v:k for k,v in obj.items()})
                    else:
                        # otherwise, echo back same object
                        stream.put_obj(obj)
            print('server: disconnect from',a)

def client():
    s = socket()
    s.connect(('localhost',9999))
    with ObjectStream(s) as stream:
        stream.put_obj([1,2,3])
        print('client:',stream.get_obj())
        stream.put_obj({1:2,3:4,5:6})
        print('client:',stream.get_obj())
        stream.put_obj(12345)
        print('client:',stream.get_obj())

run = True  # Simple global flag to control server Thread
threading.Thread(target=server).start()
client()  # Server can handle only one client at a time as written.
client()  # But can serially serve clients.
run = False

输出:

server: connect from ('127.0.0.1', 52689)
server: [1, 2, 3]
client: [3, 2, 1]
server: {1: 2, 3: 4, 5: 6}
client: {2: 1, 4: 3, 6: 5}
server: 12345
client: 12345
server: None
server: disconnect from ('127.0.0.1', 52689)
server: connect from ('127.0.0.1', 52690)
server: [1, 2, 3]
client: [3, 2, 1]
server: {1: 2, 3: 4, 5: 6}
client: {2: 1, 4: 3, 6: 5}
server: 12345
client: 12345
server: None
server: disconnect from ('127.0.0.1', 52690)

这篇关于使用套接字和python时获取pickle数据截断错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆