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
本文来自博客园,作者:河北大学-徐小波,转载请注明原文链接:https://www.cnblogs.com/xuxiaobo/p/18961209

浙公网安备 33010602011771号