跳至主要內容

ZeroMQ-Octave

Jia-Yin大约 3 分钟coursecomm

这一节将在 Octave 中使用 ZeroMQ 来进行简单的信息传递,包括请求/回应(Request/Reply)以及发布/订阅(Publish/Subscribe)模式的应用范例。

安装 ZeroMQ

如果是在 Windows 系统安装 Octave,一般来说,应该已经同时安装了 zeromq 套件,可在 Octave 中使用以下列指令确认:

>> pkg list

检查列出的清单中,是否已包括 zeromq。如果没有包括,可考虑重新安装 Octave。

如果是使用 Ubuntu,可以依以下程序进行安装:

  1. Install libzmq-dev
apt install libzmq-dev
  1. 在 Octave 中安装 ZeroMQ 套件:
pkg install -forge zeromq

使用 ZeroMQ

在 Octave 中使用 ZeroMQ 前,需要先加载它:

pkg load zeromq

你可以使用 help zeromq 命令来查看可用的函数和使用说明。

基本请求/回应模式

服务端程式码

pkg load zeromq % 载入 zeromq 程式库
more off % 输出不要使用分页模式
printf("Creating hello world server...\n");
sock = zmq_socket(ZMQ_REP); % 建立 Reply 端口
zmq_bind(sock, "tcp://*:5555"); % 监听所有网络介面的 5555 埠
printf("Waiting for clients ...\n");

while (true)
  recievedata = zmq_recv(sock, 10); % 接收最多十位元组的信息
  printf("Received %s\n", recievedata); % 列印接收到的信息
  zmq_send(sock, "World", 5); % 回应 World
endwhile

zmq_close(sock);

客户端程式码

pkg load zeromq % 载入 zeromq 程式库
more off % 输出不要使用分页模式
printf("Connecting to hello world server...\n");
sock = zmq_socket(ZMQ_REQ); % 建立 Request 端口
zmq_connect(sock, "tcp://localhost:5555"); % 连接本地端的 5555 埠

for request_nbr = 1:10
  printf("Sending Hello %d...\n", request_nbr);
  zmq_send(sock, uint8("Hello"), 5); % 传送 Hello
  printf("Waiting for server response %d... (Ctrl-C to exit)\n", request_nbr);
  recieved = zmq_recv(sock, 10); % 接收最多十位元组的信息
  printf("Received %d = %s\n", request_nbr, recieved);
endfor

zmq_close(sock);

基本发布/订阅模式

服务端程式码

pkg load zeromq % 载入 zeromq 程式库
more off % 输出不要使用分页模式
publisher = zmq_socket(ZMQ_PUB); % 建立 Publish 端口
zmq_bind(publisher, "tcp://*:5556"); % 监听本地端的 5556 埠

while (true)
  dice_number = randi(6); % 随机选出 1~6 的整数
  data = sprintf("Dice %d", dice_number); % 准备传送资料
  zmq_send(publisher, data); % 发布骰子点数信息
  data = sprintf("Score %d", randi(100)); % 准备传送资料
  zmq_send(publisher, data); % 发布成绩信息
endwhile

zmq_close(publisher);

客户端程式码

pkg load zeromq % 载入 zeromq 程式库
more off % 输出不要使用分页模式
subscriber = zmq_socket(ZMQ_SUB); % 建立 Subscribe 端口
zmq_connect(subscriber, "tcp://localhost:5556"); % 连接本地端的 5556 埠
msgfilter = "Dice"; % 过滤信息前置字串
zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, msgfilter); % 设置过滤器

total = 0;
printf("Receiving 100 dice numbers...\n");
for update_nbr = 1:100
  string = char(zmq_recv(subscriber, 128)); % 将收到的信息转成字串
  [prefix, number] = sscanf (string, "%s %d", "C"); % 使用C格式读取前置字串与点数
  printf(" %d", number); % 列印点数
  total += number; % 计算总和
endfor
printf("\n\nAverage = %.2f\n", total/100.0); % 印出骰子平均点数

%fprintf("Average temperature for zipcode '%s' was %dF\n", zipfilter, (total_temp / update_nbr));
zmq_close(subscriber);

以上示范了如何在 Octave 中使用 ZeroMQ 进行基本的信息传递。

練習 1

  1. 在 Octave 中实际操作以上的范例程式。
  2. 在第二个范例中,发布其他几种不同类型的信息,然后在客户端试著订阅不同种类的信息,并将接收到的信息加以处理。
  3. 修改连接端口,以便可以在不同计算机之间进行通信。