zmq几种模式下传输视频流

req-rep模式

客户端:

import zmq
import cv2

context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect("tcp://127.0.0.1:5556")
print('zmq client start....')
cap = cv2.VideoCapture(0)  # 读取摄像头

#客户端必须要先发送消息,然后在接收消息
#zmq模式为zmq.REP。在这种模式下,我们的程序必须要遵守recv()和send()配对使用的编程模式。
if __name__ == '__main__':
    while True:
        ret, frame = cap.read()
        if not ret:
            continue
        _, buffer = cv2.imencode('.jpg', frame)  # 编码成JPEG格式
        socket.send(buffer.tobytes())  # 发送图像数据
        socket.recv()# fixing for recv-send pair

  

服务端:

import zmq
import time
import numpy as np
import cv2

context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://127.0.0.1:5556")
print('zmq server start....')

#必须要先接收消息,然后在应答
#zmq模式为zmq.REP。在这种模式下,我们的程序必须要遵守recv()和send()配对使用的编程模式。
if __name__ == '__main__':
    while True:
        try:
            msg = socket.recv()
            socket.send_string('done')
        except Exception as e:
            print('socket.recv fail %s' % e)
            continue
        
        img = cv2.imdecode(np.frombuffer(msg, dtype=np.uint8), 1)  # 解码图像
        try:
            cv2.imshow("zmq_video_reqrep_rep_server", img)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
        except Exception as e:
            print('imshow fail %s' % e)
            pass
        

  

效果:

 

pub-sub模式

客户端:

import zmq
import cv2

context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.connect("tcp://127.0.0.1:5555")  # 本地绑定端口
print('zmq client start....')

cap = cv2.VideoCapture(0)  # 读取摄像头

while True:
    ret, frame = cap.read()
    if not ret:
        continue
    _, buffer = cv2.imencode('.jpg', frame)  # 编码成JPEG格式
    socket.send(buffer.tobytes())  # 发送图像数据

  

服务端:

import zmq
import numpy as np
import cv2

context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.bind("tcp://127.0.0.1:5555")
socket.setsockopt(zmq.SUBSCRIBE, b"")  # 订阅所有消息
print('zmq server start....')

while True:
    msg = socket.recv()  # 接收图像数据
    img = cv2.imdecode(np.frombuffer(msg, dtype=np.uint8), 1)  # 解码图像
    
    try:
        cv2.imshow("zmq_video_pubsub_sub_server", img)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    except Exception as e:
        print(e)
        pass

  

效果:

 

 

push-pull模式

客户端:

import zmq
import numpy as np
import cv2

context = zmq.Context()
socket = context.socket(zmq.PULL)
socket.bind("tcp://127.0.0.1:5558")
    
while True:
    msg = socket.recv()
    img = cv2.imdecode(np.frombuffer(msg, dtype=np.uint8), 1)  # 解码图像
    try:
        cv2.imshow("zmq_video_pushpull_client", img)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    except Exception as e:
        print(e)
        pass

  

worker端:

import zmq
import numpy as np
import cv2
import time
from datetime import datetime

context = zmq.Context()

socket1 = context.socket(zmq.PULL)
socket1.connect("tcp://127.0.0.1:5557")

socket2 = context.socket(zmq.PUSH)
socket2.connect("tcp://127.0.0.1:5558")

while True:
    current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    data = socket1.recv()
    print("[%s]正在转发..." % current_time)
    socket2.send(data)

  

服务端:

import zmq
import time
import cv2

context = zmq.Context()
socket = context.socket(zmq.PUSH)
socket.bind("tcp://127.0.0.1:5557")

while True:
    cap = cv2.VideoCapture(0)  # 读取摄像头
    
    while True:
        ret, frame = cap.read()
        if not ret:
            continue
        _, buffer = cv2.imencode('.jpg', frame)  # 编码成JPEG格式
        socket.send(buffer.tobytes())  # 发送图像数据

  

效果:

 

 

需要注意的是:

1、zmq模式为zmq.REP。在这种模式下,我们的程序必须要遵守recv()和send()配对使用的编程模式。

否则会报错:Operation cannot be accomplished in current state

2、服务端一般需要bind,客户端需要connect

posted @ 2025-07-02 11:26  河北大学-徐小波  阅读(274)  评论(0)    收藏  举报