How to send message between C++ and Python Program Using ZeroMQ in Raspberry Pi
First we need the following packages.
- ZeroMQ
- gcc 4.8 or later
- Cmake
- Pyzmq
How to Install Necessary Packages
1.Follow this link to install ZeroMQ
2.Follow this link to install gcc 4.8
3.Follow this link to install Cmake
4.Follow this link to install Pyzmq
Additional Note
Clinet use connect
to connect the server. Server use bind
to set its server address. In this post, localhost
is used. If you want to connect across the LAN network, localhost can be changed to real IP addess such as "tcp://192.168.1.104:5555"
Writing Client Program With Python
We will create a client program with Python. You can use with your favorite editor (in my case, I’m using gedit
)
$ cd ~/
$ mkdir ClientProgram
$ cd ClientProgram
$ gedit client.py
Then paste the following code into gedit editor. Save and exit the program.
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
Writing Server Program With C++
In C++, we need more steps to compile. Now we will create server program with C++.
$ cd ~/
$ mkdir ServerProgram
$ cd ServerProgram
$ gedit main.cpp
Then paste the following code into gedit editor. Save and exit the gedit editor.
#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;
}
Now we will create a CMake File. Assuem that we are still in ServerProgram folder. Type the following command.
$ gedit CMakeLists.txt
Then paste the following code into gedit editor. Then save and exit the program.
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})
Now we are going to compile the program with CMake. Assume here again that we are still in ServerProgram folder.
$ mkdir tmp
$ cd tmp
$ cmake ..
$ make
After the successful compile, you should see the following lines on terminal.
Scanning dependencies of target ZmqProject
[ 50%] Building CXX object CMakeFiles/ZmqProject.dir/main.cpp.o
[100%] Linking CXX executable ZmqProject
[100%] Built target ZmqProject
Testing both python and c++ program
We will first run the client program first. Go to the ClientProgram folder that we first created. Then run the program.
$ cd ~/
$ cd ClientProgram
$ python client.py
Note: we will note see any output yet since we haven’t run the server program
Here we should get another tab from terminal by pressing Ctrl
+ Alt
+T
. Now we go to ServerProgram folder and then run the program.
$ cd ~/
$ cd ServerProgram
$ cd tmp
$ ./ZmqProject
Once the both programs are started to run. you should see these outputs. You should see this output from the server side.
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
You should see this output from the client side.
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++
Note: the cleint program will exit once the program finishs the loop. However, the server will keep listening any incoming message. This is how the programs are written.
This comment has been removed by the author.
ReplyDeleteVery nice...
ReplyDeleteI have a problem, I cant resolve.
I havve zmq publisher in python and zmq subscricriber in c++, but communication is not working. Do you happen to know a working example?
This pretty much worked out of the box for me! Good job. Ran into some incompatability issues with libsodium/zmq but 1.0.12/4.1.4 is a valid combination.
ReplyDeleteI have this error an I cannot find a way to proceed with the make
ReplyDeleteerror: ‘socket’ is not captured socket.send(reply);
What am I missing?