提取包需要8个字节的错误套接字python缓冲区

问题描述

我有以下代码,我将从客户端向服务器发送中间预测结果。

客户

document.title = document.getElementById('customerName').value +' ' + 'Caller' ;

服务器

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

运行上面的代码时,我遇到以下错误

msg_size = struct.unpack(“ Q”,packed_msg_size)[0] struct.error:解压缩需要8个字节的缓冲区

谢谢

解决方法

您还没有解决正常的连接结束问题。如注释中所述,当客户端关闭连接时,您击中if not packet: break,但这只会使您跳出内循环,并继续尝试处理不存在的消息。那里还有另一个错误,您无法清除每条消息data

当嵌套循环时,尤其是在发现处理结束几步的通信中,我发现最好将工作分解为角色更狭窄的多个功能。在这里,您希望一次只接收一条消息,将其构建到python对象中,然后使用它。三个功能的三项功能。

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)