使用套接字和python时获取pickle数据截断错误 [英] Getting pickle data truncated error while working with sockets and python
问题描述
问题来了.我试图通过套接字发送大量二进制图像代码,这是 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屋!