【问题标题】:Sending Bytes properly to client正确发送字节给客户端
【发布时间】:2019-08-11 15:28:26
【问题描述】:

在 Python 中,我正在尝试构建一个简单的服务器/客户端应用程序,将视频字节发送到客户端。

几个月来我一直在努力解决这个问题。

服务器正在监听连接,每秒接收这么多数据,长度为 1316

例如: data = sock_reciever.recv(16000000)

如果我打印data,我会得到:

b'G\x05\x14\x1e\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x1f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x11\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x12\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x13\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x17\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\xff\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

收到后,我可以通过sock_sender.sendto(data, (SENDMCAST_GRP, SENDMCAST_PORT)) 将其发回,然后在 VLC 播放器中观看视频。

最后,我想把这些数据通过conn.send(data)的socket发送给客户端。


但是,在客户端,我认为数据的输入顺序是错误的。

我比较了服务器和客户端之间的数据,它看起来是相同的,但它是在客户端建立起来的,这可能会导致某种溢出。

在客户端,我将通过data = sock_reciever.recv(16000000) 传入的数据通过sock_sender.sendto(data, (SENDMCAST_GRP, SENDMCAST_PORT)) 发回。

但我在客户端得到的结果与在服务器端不同。

如何向此数据添加标头以确保它按顺序到达客户端?

如果可能的话,请像解释鱼对氧气的含义一样向我解释这一点。

我正在使用哪些套接字

我正在尝试在服务器和客户端之间使用 TCP 套接字。我认为使用流套接字会更可靠,但我可能错了,唯一的原因是我想做反向连接,以便客户端连接到服务器然后接收数据。

我也使用sock_sender.sendto(data, (SENDMCAST_GRP, SENDMCAST_PORT))只是在客户端中继传入的数据,它不是服务器和客户端之间的实际连接。

用于服务器/客户端通信的套接字 被称为sock_client。

这是服务器端代码:

sock_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# recieves connection from client
conn, address = sock_client.accept()

# sends data to client
conn.send(data)

客户端设置如下:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

data = s.recv(2400000)

然后,数据只是通过sock_sender.sendto(data, (SENDMCAST_GRP, SENDMCAST_PORT)) 转发回来供其他应用程序使用。

我需要确保客户端/服务器套接字连接之间的数据准确完整。

【问题讨论】:

    标签: python-3.x byte binary-data


    【解决方案1】:

    让我稍微解释一下。视频可以借助 struct 以字节的形式发送。它是 python 标准库字符串服务的一部分。 它将字符串解释为打包的二进制数据,并在 Python 值和表示为 Python 字符串的 C 结构之间执行转换。这有助于处理文件、套接字网络连接和其他源中的二进制数据。在 server.py 中,帧矩阵被腌制转储为变量 a 中的字符串,然后使用 struct.pack 添加参考有效载荷大小(对于 a 中的字符串)。 payload_size 使用 + 附加到 a ,然后 .sendall 发送整个帧。简单解释一下,假设我们的框架只是 3x3 矩阵:

    frame=np.array([[1,2,3],[4,5,6],[7,8,9]])

    a = pickle.dumps(帧)

    框架的腌制形式如下所示为字符串:

    b'\x80\x03cnumpy.core.multiarray\n_reconstruct\nq\x00cnumpy\nndarray\nq\ x01K\x00\x85q\x02C\x01bq\x03\x87q\x04Rq\x05(K\x01K\x03K\x03\x86q\x06cnumpy \ndtype\nq\x07X\x02\x00\x00\x00i4q\x08K\x00K\x01\x87q\tRq\n(K\x03X\x01\x00 \x00\x00

    这里的payload_size:len(a)是193,它的4字节'L'格式的字符串表示是b'\xc1\x00\x00\x00'。 然后,message = struct.pack("L", len(a))+a

    b'\xc1\x00\x00\x00\x80\x03cnumpy.core.multiarray\n_reconstruct\nq\x00cnumpy\nndarray\nq\ x01K\x00\x85q\x02C\x01bq\x03\x87q\x04Rq\x05(K\x01K\x03K\x03\x86q\x06cnumpy \ndtype\nq\x07X\x02\x00\x00\x00i4q\x08K\x00K\x01\x87q\tRq\n(K\x03X\x01\x00 \x00\x00

    现在消息还包含数据前面的payload_size。长度(消息)= 197。 在 client.py 中,s.recv(4096) 意味着最多 4096 个字节将通过阻塞调用接收。 数据以每个数据包 4096 字节的形式附加到字符串中。其余部分非常明显。 server.py 和 client.py 的参考工作版本如下。首先运行 server.py,然后在另一个命令窗口中运行 client.py。将显示发送和接收的帧。您可以增加最大字节数。我希望这能解决你的问题!

    server.py

        import socket,cv2,pickle
        import struct
        serversocket = socket.socket(
                    socket.AF_INET, socket.SOCK_STREAM)
        host = socket.gethostname()
        port = 9999
        serversocket.bind((host, port))
        serversocket.listen(5)
    
        while True:
            clientsocket,addr = serversocket.accept()
    
            print("Got a connection from %s" % str(addr))
            if clientsocket:
                vid = cv2.VideoCapture(0)
                while(vid.isOpened()):
                    img, frame = vid.read()
                    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
                    print(frame)
                    a = pickle.dumps(frame)
                    message =struct.pack("L", len(a))+a
                    clientsocket.sendall(message)
                    cv2.imshow('Transmitted',frame)
                    key = cv2.waitKey(1) & 0xFF
                    if key == ord("q"):
                        clientsocket.close()
    

    client.py

        import socket,cv2,pickle
        import struct
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        host = socket.gethostname()
        port = 9999
        s.connect((host, port))
        data = b""
        payload_size = struct.calcsize("L") 
        while True:
            while len(data) < payload_size:
                packet= s.recv(4096)
                if not packet: break
                data += packet
            packed_msg_size = data[:payload_size]
            data = data[payload_size:]
            msg_size = struct.unpack("L", packed_msg_size)[0]
            while len(data) < msg_size:
                data += s.recv(4096)
            frame_data = data[:msg_size]
            data = data[msg_size:]
            frame=pickle.loads(frame_data)
            cv2.imshow('Received',frame)
            key = cv2.waitKey(1) & 0xFF
            if key == ord("q"):
                break
        s.close()
    

    【讨论】:

      猜你喜欢
      • 2017-01-12
      • 1970-01-01
      • 1970-01-01
      • 2013-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-09
      相关资源
      最近更新 更多