【精品教程】ZeroMQ中C++与Python通信 – QADoor 问答门
QADoor 问答门

【精品教程】ZeroMQ中C++与Python通信

原文参考:http://osdevlab.blogspot.com/2015/12/how-to-send-message-between-c-and.html

本文解决的问题是:使用ZeroMQ,如何在C++与Python中进行消息通信呢?

我们以C++为服务端,Python为客户端。

首先我们要在服务端安装如下的一些包。

如何安装上述依赖包呢?

点击此处学会安装ZeroMQ

点击此处学会安装Gcc 4.8

点击此处学会安装Cmake

点击此处学会安装Pyzmq

 

通信场景

客户端使用connect去连接到服务端,服务端使用bind函数绑定服务端ip。在本文中,服务端绑定的是"localhost"。如果需要通过局域网访问服务端,那么要访问服务端的真实局域网ip,比如"tcp://192.168.1.104:5555"

 

Python客户端开发

我们使用gedit进行client.py代码编写:

$ cd ~/
$ mkdir ClientProgram
$ cd ClientProgram
$ gedit client.py

client.py内容为:

import zmq

context = zmq.Context()
socket = context.socket(zmq.REQ)
port = "5555"
socket.connect ("tcp://localhost:%s" % port)

for i in range (1,10):
    socket.send ("saying hello from python")
    message = socket.recv()
    print "Received reply from server:", message

然后保存退出即可,这样客户端代码便完成了。

 

C++服务端开发

在c++中,我们同样使用gedit来编辑代码:

$ cd ~/
$ mkdir ServerProgram
$ cd ServerProgram
$ gedit main.cpp

 

然后main.cpp的代码内容为:

#include <zmq.hpp>
#include <iostream>
#include <unistd.h>

int main() {
    //  Prepare our context and socket
    zmq::context_t context(1);
    zmq::socket_t socket(context, ZMQ_REP);
    socket.bind("tcp://*:5555");

    // forever loop
    while (true) {
        zmq::message_t request;

        //  Wait for next request from client
        socket.recv(&request);
        std::string replyMessage = std::string(static_cast<char *>(request.data()), request.size());
//        std::string replyMessage = std::string((request.data())., request.size());
        // Print out received message
        std::cout << "Received from client: " + replyMessage << std::endl;

        //  See the gradual sending/replying from client
        sleep(1);

        //  Send reply back to client
        std::string msgToClient("greeting from C++");
        zmq::message_t reply(msgToClient.size());
        memcpy((void *) reply.data(), (msgToClient.c_str()), msgToClient.size());
        socket.send(reply);
    }
    return 0;
}

然后我们创建一份CMake文件,键入如下命令:

gedit CMakeLists.txt

CMakeLists.txt内容为:

cmake_minimum_required(VERSION 3.3)
project(ZmqProject)

# This will file libzmq.so file from /usr/local/lib
FIND_FILE(ZMQLIB libzmq.so /usr/local/lib)
IF(NOT ZMQLIB)
    MESSAGE(SEND_ERROR "Ah.. Cannot find library libzmq.so.")
ENDIF(NOT ZMQLIB)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)

add_executable(ZmqProject ${SOURCE_FILES})
# The following line will link with libzmq.so
TARGET_LINK_LIBRARIES( ZmqProject ${ZMQLIB})

现在我们要用CMake编译程序。假设我们仍然在ServerProgram文件夹中。

$ mkdir tmp
$ cd tmp
$ cmake ..
$ make

成功编译后,您应该在终端上看到以下几行

Scanning dependencies of target ZmqProject
[ 50%] Building CXX object CMakeFiles/ZmqProject.dir/main.cpp.o
[100%] Linking CXX executable ZmqProject
[100%] Built target ZmqProject

测试

我们将首先运行客户端程序。转到我们第一次创建的ClientProgram文件夹。然后运行程序。

$ cd ~/
$ cd ClientProgram
$ python client.py

然后在终端中使用快捷键"Ctrl+Alt+T"新开一个shell窗口,输入如下命令启动C++服务端:

$ cd ~/
$ cd ServerProgram
$ cd tmp
$ ./ZmqProject

一旦这两个程序开始运行。你应该看到这些输出。你应该从服务器端看到这个输出:

Received from client: saying hello from python
Received from client: saying hello from python
Received from client: saying hello from python
Received from client: saying hello from python
Received from client: saying hello from python
Received from client: saying hello from python
Received from client: saying hello from python
Received from client: saying hello from python
Received from client: saying hello from python

你应该从客户端看到这个输出:

Received reply from server: greeting from C++
Received reply from server: greeting from C++
Received reply from server: greeting from C++
Received reply from server: greeting from C++
Received reply from server: greeting from C++
Received reply from server: greeting from C++
Received reply from server: greeting from C++
Received reply from server: greeting from C++
Received reply from server: greeting from C++

注意:一旦程序完成循环,客户端程序将退出。但是,服务器将不断收听任何传入的消息。