Cv2:从套接字接收完整数据的问题

我正在尝试通过套接字发送帧,并且在编码后它们通常是 50 000 - 80 000 字节,所以我通过循环接收数据,但是由于客户端总是发送帧,所以下面代码中的循环不会中断,所以当我运行时没有任何反应并且接收循环继续


客户


import socket

import cv2

import time

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

s.connect(("127.0.0.1",60124))

camera = cv2.VideoCapture(0)

while True :

    r , f = camera.read()

    f = cv2.imencode(".jpg",f)[1].tostring()

    s.sendall(f)

服务器


import socket

import numpy as np

import cv2

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

s.bind(("127.0.0.1",60124))

s.listen(5)

c , a = s.accept()


while True :

    data = ""

    while True:

        f = c.recv(1024)

        if not f :

            break

        data += f

    x = np.fromstring(data , np.uint8)

    var = cv2.imdecode(x , cv2.IMREAD_COLOR)

    cv2.imshow("Camera" , var)

    cv2.waitKey(1)

请帮助


吃鸡游戏
浏览 87回答 1
1回答

波斯汪

我建议你先发送长度,然后发送数据。当服务器接收到“有效负载”长度时,它知道需要多少数据字节。客户端:len(f)以8字节形式发送发送数据f服务器:接收8字节以获取len_f.接收len_f数据字节。无需以 1024 字节块的形式接收数据。在我的示例中,len_f被编码为base64格式。发送的字节数len_f始终为 8 个字节(由于 base64 自动填充)。data您也可以编码base64。如果您通过 HTTP 发送数据,这一点很重要。我将base64图像数据的编码/解码放在注释中。只有长度被编码为base64(您也可以将长度作为文本格式发送)。客户:import socketimport numpy as npimport cv2import base64s = socket.socket(socket.AF_INET , socket.SOCK_STREAM)s.connect(("127.0.0.1", 60124))width, height, n_frames = 640, 480, 100  # 100 frames, resolution 640x480for i in range(n_frames):    # Generate synthetic image:    img = np.full((height, width, 3), 60, np.uint8)    cv2.putText(img, str(i+1), (width//2-100*len(str(i+1)), height//2+100), cv2.FONT_HERSHEY_DUPLEX, 10, (30, 255, 30), 20)  # Green number    # JPEG Encode img into f    _, f = cv2.imencode('.JPEG', img)    # Encode jpeg_img to base64 format    #f = base64.b64encode(f)    # Get length of f and encode to base64    #f_len = base64.b64encode((len(f)).to_bytes(4, byteorder='little'))    f_len = base64.b64encode((len(f)).to_bytes(4, byteorder='little'))    # Send the length first - so the server knows how many bytes to expect.    s.sendall(f_len) # Send 8 bytes (assumption: b64encode of 4 bytes will be 8 bytes due to the automatic padding feature).    s.sendall(f)s.close()服务器:import socketimport numpy as npimport cv2import base64s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.bind(("127.0.0.1", 60124))s.listen(5)c, a = s.accept()while True:    # Read 8 bytes that tells the length of encoded image to be expected.    data = c.recv(8)    if len(data) != 8:        break    # Decode f_len from base64    f_len = base64.decodebytes(data)    # Convet from array of 4 bytes to integer value.    f_len = int.from_bytes(f_len, byteorder='little')    #f = c.recv(1024)    # Receive the encoded image.    data = c.recv(f_len)    if len(data) != f_len:        break    #x = base64.decodebytes(data)  # Decode base64    #x = np.fromstring(x , np.uint8)    x = np.fromstring(data, np.uint8)    var = cv2.imdecode(x, cv2.IMREAD_COLOR)    if var is None:        print('Invalid image')    else:        cv2.imshow("Camera" , var)        cv2.waitKey(100)s.close()cv2.destroyAllWindows()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python