Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 向客户端发送视频帧_Python_Sockets_Opencv_Tkinter - Fatal编程技术网

Python 向客户端发送视频帧

Python 向客户端发送视频帧,python,sockets,opencv,tkinter,Python,Sockets,Opencv,Tkinter,我目前正在使用OpenCV阅读视频帧 在服务器端,我使用cPickle.dumps()序列化框架: 在客户端,我使用cPickle.load()序列化框架: 加载(数据)导致ValueError:不安全的字符串pickle。我做错了什么?我想阅读客户端的框架,并在tkinter窗口中显示它。我到处都查了9个多小时,但找不到解决办法 编辑1: 我也试过: 服务器端 flag, frame = cap.read() if flag: size = sys.getsizeof(frame)

我目前正在使用OpenCV阅读视频帧

在服务器端,我使用cPickle.dumps()序列化框架:

在客户端,我使用cPickle.load()序列化框架:

加载(数据)导致ValueError:不安全的字符串pickle。我做错了什么?我想阅读客户端的框架,并在tkinter窗口中显示它。我到处都查了9个多小时,但找不到解决办法

编辑1:

我也试过:

服务器端

flag, frame = cap.read()
if flag:
    size = sys.getsizeof(frame)
    client_socket.send(str(size))
    client_socket.sendall(cPickle.dumps(frame.tolist()))
flag, frame = cap.read()
if flag:
   frame = cPickle.dumps(frame)
   size = len(frame)
   p = struct.pack("I", size)
   client_socket.send(p)
   client_socket.sendall(frame)
客户端

size = sock.recv(4000)
data = sock.recv(int(size))
frame = cPickle.loads(data) # Causes EOFError 
sizep = sock.recv(struct.calcsize("I"))
data_size = struct.unpack("I",sizep)
print type (data_size) # tuple - has (11026730, )
data = sock.recv(int(data_size[0]))
frame = cPickle.loads(data) # ValueError: insecure string pickle
编辑2: 服务器端

flag, frame = cap.read()
if flag:
    size = sys.getsizeof(frame)
    client_socket.send(str(size))
    client_socket.sendall(cPickle.dumps(frame.tolist()))
flag, frame = cap.read()
if flag:
   frame = cPickle.dumps(frame)
   size = len(frame)
   p = struct.pack("I", size)
   client_socket.send(p)
   client_socket.sendall(frame)
客户端

size = sock.recv(4000)
data = sock.recv(int(size))
frame = cPickle.loads(data) # Causes EOFError 
sizep = sock.recv(struct.calcsize("I"))
data_size = struct.unpack("I",sizep)
print type (data_size) # tuple - has (11026730, )
data = sock.recv(int(data_size[0]))
frame = cPickle.loads(data) # ValueError: insecure string pickle

您最多接收4000字节的以下数据

data = sock.recv(4000)
但信息远不止这些。您必须完全阅读消息,否则消息将被截断,这就解释了pickle错误。例如,您可以这样做:

packets = []
while True:
    b = sock.recv(4096)
    if b:
        packets.append(b)
    else:
        break

data = "".join(packets)
它将读取套接字,直到没有任何内容可读取为止。我将每个数据包放在一个列表中,这样我就可以在之后使用
str.join
(比字符串串联更快)

现在,
数据
可以加载到pickle中

注意:它不能解决self.ImageLabel.configure(image=frame)的问题。确保将所需的数组类型传递给此方法

编辑:现在你已经编辑了你的问题,你有更多的问题

  • 首先,在使用pickle进行序列化之前计算对象的大小,这是不正确的,您应该使用
    len(拾取的对象)
  • 然后,您使用recv(4000)读取大小:这样做只消耗了一部分缓冲区,而您不知道整数作为字符串的大小,因此大小问题没有得到解决。如果需要首先发送大小,则需要使用
    struct.pack
    对其进行编码,并在客户端使用
    struct.unpack
    对其进行解码
  • 当您拥有正确的大小时,您可以读取数据
这是我的建议(您需要导入
struct
):

服务器端:

flag, frame = cap.read()
if flag:
    data = cPickle.dumps(frame)  # serialize
    data_size = len(data)        # nb of bytes of serialized data
    p = struct.pack("I",data_size) # encode size
    client_socket.send(p)  # send encoded size
    client_socket.sendall(data)  # send serialized data
客户端:

sizep = sock.recv(struct.calcsize("I")) # first thing: recieved encoded size
data_size = struct.unpack("I",sizep)  # decode size
data = sock.recv(data_size)          # read data size
frame = cPickle.loads(data)          # unserialize

@Jean-Françoisfare cap.read()是OpenCV的函数。它给了我们一个机会object@Jean-Françoisfare cPickle.dumps(frame.tolist())在尝试cPickle.load(data)时会导致EOFError。我不确定self.ImageLabel.configure(image=frame)是否接受数据数组。在发送数据数组之前是否可以打印
frame
?这里似乎有些东西被破坏了…@Jean Françoisfare打印帧的结果:其中frame=cPickle.dumps(frame.tolist())您没有添加“…”,是吗?请查看我的编辑。服务器将发送许多帧。因此,在发送实际帧之前,我首先发送了帧的大小,但它仍然会导致错误。如果消息的大小是个问题,这难道不能解决这个问题吗?我使用struct尝试了您的解决方案。它仍然在给出ValueError:不安全的字符串pickle。请参见编辑2。是否可以在发射前和发射后打印尺寸?