检索解包需要 8 字节错误套接字缓冲区 python
Retrieving unpack requires a buffer of 8 bytes error socket python
我有以下代码我正在将中间预测结果从客户端发送到服务器。
客户
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host_name = socket.gethostname()
host_ip = 'localhost'
print('HOST IP:', host_ip)
port = 9999
socket_address = (host_ip, port)
server_socket.bind(socket_address)
server_socket.listen(5)
while True:
client_socket, addr = server_socket.accept()
print('GOT CONNECTION FROM:', addr)
if client_socket:
vid = cv2.VideoCapture("D:/testing.mp4")
while (vid.isOpened()):
img, frame = vid.read()
image = img_to_array(frame)
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
image = preprocess_input(image)
preds = model.predict(image)
a = pickle.dumps(preds)
message = struct.pack("Q", len(a)) + a
client_socket.sendall(message)
client_socket.close()
服务器
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host_ip = 'localhost'
port = 9999
client_socket.connect((host_ip, port))
data = b""
payload_size = struct.calcsize("Q")
while True:
while len(data) < payload_size:
packet = client_socket.recv(4 * 1024)
if not packet: break
data += packet
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack("Q", packed_msg_size)[0]
while len(data) < msg_size:
data += client_socket.recv(4 * 1024)
frame_data = data[:msg_size]
data = data[msg_size:]
frame = pickle.loads(frame_data)
虽然运行上面的代码我遇到了下面的错误
msg_size = struct.unpack("Q", packed_msg_size)[0]
struct.error: 解包需要8字节的缓冲区
谢谢
您还没有解决连接正常结束的问题。如评论中所述,当客户端关闭连接时,您点击 if not packet: break
但这只会使您脱离内部循环,并且您继续尝试处理 non-existent 消息。那里还有另一个错误,您没有清除每条消息 data
。
当嵌套循环时,尤其是在发现处理结束的通信中向下几步时,我发现最好将工作分解为具有更严格定义的角色的多个函数。在这里,您希望一次只接收一条消息,将其构建到 python 对象中,然后使用它。 3 种功能用于三件事。
def do_the_things():
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host_ip = 'localhost'
port = 9999
client_socket.connect((host_ip, port))
while True:
frame = recv_frame(client_socket)
if frame is None:
break
payload_size = struct.calcsize("Q")
def recv_obj(client_socket):
data = recvall(client_socket, payload_size)
if len(data) < payload_size:
if not data:
# client closed after last message, assume all is well
return None
else:
raise IOError("Truncated message")
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack("Q", packed_msg_size)[0]
remaining_data = recvall(client_socket, msg_size)
if len(remaining_data) < msg_size:
raise IOError("Truncated message")
obj = pickle.loads(data + remaining_data)
return obj
def recvall(sock, count):
"""Keep receiving up to `count` bytes, returning partial result
if connection closed normally by remote."""
data_bufs = []
while count:
data = sock.recv(count)
if not data:
break
count -= len(data)
data_bufs.append(data)
return b"".join(data_bufs)
我有以下代码我正在将中间预测结果从客户端发送到服务器。
客户
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host_name = socket.gethostname()
host_ip = 'localhost'
print('HOST IP:', host_ip)
port = 9999
socket_address = (host_ip, port)
server_socket.bind(socket_address)
server_socket.listen(5)
while True:
client_socket, addr = server_socket.accept()
print('GOT CONNECTION FROM:', addr)
if client_socket:
vid = cv2.VideoCapture("D:/testing.mp4")
while (vid.isOpened()):
img, frame = vid.read()
image = img_to_array(frame)
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
image = preprocess_input(image)
preds = model.predict(image)
a = pickle.dumps(preds)
message = struct.pack("Q", len(a)) + a
client_socket.sendall(message)
client_socket.close()
服务器
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host_ip = 'localhost'
port = 9999
client_socket.connect((host_ip, port))
data = b""
payload_size = struct.calcsize("Q")
while True:
while len(data) < payload_size:
packet = client_socket.recv(4 * 1024)
if not packet: break
data += packet
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack("Q", packed_msg_size)[0]
while len(data) < msg_size:
data += client_socket.recv(4 * 1024)
frame_data = data[:msg_size]
data = data[msg_size:]
frame = pickle.loads(frame_data)
虽然运行上面的代码我遇到了下面的错误
msg_size = struct.unpack("Q", packed_msg_size)[0] struct.error: 解包需要8字节的缓冲区
谢谢
您还没有解决连接正常结束的问题。如评论中所述,当客户端关闭连接时,您点击 if not packet: break
但这只会使您脱离内部循环,并且您继续尝试处理 non-existent 消息。那里还有另一个错误,您没有清除每条消息 data
。
当嵌套循环时,尤其是在发现处理结束的通信中向下几步时,我发现最好将工作分解为具有更严格定义的角色的多个函数。在这里,您希望一次只接收一条消息,将其构建到 python 对象中,然后使用它。 3 种功能用于三件事。
def do_the_things():
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host_ip = 'localhost'
port = 9999
client_socket.connect((host_ip, port))
while True:
frame = recv_frame(client_socket)
if frame is None:
break
payload_size = struct.calcsize("Q")
def recv_obj(client_socket):
data = recvall(client_socket, payload_size)
if len(data) < payload_size:
if not data:
# client closed after last message, assume all is well
return None
else:
raise IOError("Truncated message")
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack("Q", packed_msg_size)[0]
remaining_data = recvall(client_socket, msg_size)
if len(remaining_data) < msg_size:
raise IOError("Truncated message")
obj = pickle.loads(data + remaining_data)
return obj
def recvall(sock, count):
"""Keep receiving up to `count` bytes, returning partial result
if connection closed normally by remote."""
data_bufs = []
while count:
data = sock.recv(count)
if not data:
break
count -= len(data)
data_bufs.append(data)
return b"".join(data_bufs)