Robotics/C++

[ZeroMQ] C++와 Python 프로그램간 통신 연동 예제

콩지니어 2023. 1. 3. 16:39
반응형

Inter-process Commnuication으로 TCP/IP를 주로 이용해 왔는데, 기존에 쓰던 boost 보다 요즘은 더 많이 쓰는 것으로 보이는 zeroMQ 라이브러리를 이용해 C++ 프로그램과 Python 프로그램 사이 통신을 시도해보았습니다.

C++ Setup

소스코드를 직접 빌드할 수도 있고, vcpkg로 설치하여 사용할 수도 있음. cmake 프로젝트로 개발할 예정이기 때문에 간단하게 vcpkg로 설치 (vcpkg를 우선 설치할 것)

.\vcpkg.exe install cppzmq:x64-windows

Python Setup

Python은 pip으로 간단히 설치할 수 있음. 가급적 venv를 만들어서 사용하는 것을 추천.

pip install pyzmq
 

C++ Server 생성

Visual Studio를 기준으로, 새 cmake project를 생성한 뒤,  CMakeLists.txt를 아래와 같이 수정 및 저장

# CMakeList.txt : CMake project for zmq_trial, include source and define
# kongineer Tistory kongineer.tistory.com
#
cmake_minimum_required (VERSION 3.8)

project ("zmq_trial")

#find cppzmq wrapper, installed by make of cppzmq
find_package(cppzmq CONFIG REQUIRED)

# Add source to this project's executable.
add_executable (zmq_trial "zmq_trial.cpp" "zmq_trial.h")

target_link_libraries(${PROJECT_NAME} PRIVATE cppzmq cppzmq-static)

여기서, zmq_trial은 임의로 정한 프로젝트 이름 이므로, 각자의 프로젝트명에 맞게 수정할 것.

저장 후 자동으로 아래와 같이 CMake generation이 정상종료되면 ok.

메인이 되는 cpp 파일을 아래와 같이 수정

// zmq_trial.cpp : Defines the entry point for the application.
// slightly modifed code from http://kr.zeromq.org/cpp:hwserver
// kongineer Tistory kongineer.tistory.com
//

#include <zmq.hpp>
#include <string>
#include <iostream>

#ifdef _WIN32
#include<Windows.h>
#elif defined __unix__
#include <unistd.h>
#endif

void delay(int msec)
{
#ifdef _WIN32
    Sleep(msec);
#elif defined __unix__
    sleep(msec);
#endif
}

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

    while (true) {
        zmq::message_t request;

        //  Wait for next request from client
        socket.recv(&request);
        std::cout << "Received Hello" << std::endl;

        //  Do some 'work'
        delay(100);

        //  Send reply back to client
        zmq::message_t reply(5);
        memcpy((void*)reply.data(), "World", 5);
        socket.send(reply);
    }
    return 0;
}

빌드 및 실행을 시킨 후 빌드가 완료되면 빈 커맨드창이 뜨면서 클라이언트로 부터의 요청을 기다리게 됨.

Python Client

아래와 같이 python 파일을 만든 후 실행

"""
an example code from https://zeromq.org/languages/python/
"""

import zmq

context = zmq.Context()

#  Socket to talk to server
print("Connecting to hello world server…")
socket = context.socket(zmq.REQ)
socket.connect("tcp://localhost:5555")

#  Do 10 requests, waiting each time for a response
for request in range(10):
    print("Sending request %s …" % request)
    socket.send(b"Hello")

    #  Get the reply.
    message = socket.recv()
    print("Received reply %s [ %s ]" % (request, message))

10번 연속해서 메세지를 주고 받는 코드임.

이를 실행하면 앞서 실행하여 대기중인 C++ 서버 프로그램에서 메세지를 받고 응답을 보내는 프로세스를 0.1초 간격으로 10번 실행하는 것을 확인할 수 있음

정보를 주고 받는 기록

 

'Robotics > C++' 카테고리의 다른 글

CMake 디렉토리(경로)를 변수로 받아 사용하기  (12) 2023.01.04
CMake와 Eigen 라이브러리 묶기  (0) 2019.01.01