簡體   English   中英

如何使用 zeromq(zmq) 在服務器和客戶端之間發送整數值?

[英]How to send integer values between server and client using zeromq(zmq)?

我有一個帶有 zmq ( ZeroMQ ) lib 的 C++ 服務器和客戶端代碼。 我想向客戶端發送整數值。

我已經通讀了 zmq 的手冊,但是我在從服務器向客戶端發送字符數組以外的任何內容時遇到問題。

任何人都可以幫助我的代碼? 提前致謝。

您只需要一種消息格式。

大小有效將是一個結構:

發送方

struct Message
{
  uint32_t one;
  uint64_t two;
};

Message msg;
msg.one = 1;
msg.two = 20;
send(&msg, sizeof(Message));

或者,如果您想要更靈活的東西,可以發送json等

接收方:

假設您使用cppzmq標頭

Message* msg;
zmq::message_t zmsg;
sock->recv(&zmsg);
msg = (Message*)zmsg.data();
int one - msg->one;

在通過 zmq 發送數據包之前對數據包進行編碼總是更好。 對於大型數據集或數組,避免這種情況也可能存在問題。 作為一般示例,讓我以 Python 客戶端和 C++ 服務器之間的REQ/REP套接字為例,分享如何發送編碼數據包; 客戶端通過以 base64 編碼形式發送圖像來請求服務器。 對此,服務器通過返回結果數組進行回復,再次編碼為C string

蟒蛇客戶端

import time
import zmq
import base64

def producer():
    context = zmq.Context()
    zmq_socket = context.socket(zmq.REQ)
    zmq_socket.connect("tcp://127.0.0.1:5556")
    # Start your result manager and workers before you start your producers

    # Read image to send
    f = open("/home/virus/Desktop/optimisation/test.ppm",'rb')
    bytes = bytearray(f.read());
    # encode
    strng = base64.b64encode(bytes)

    # send/Request
    start = time.time();
    zmq_socket.send(strng)

    # Get reply
    result = zmq_socket.recv();
    # Convert bytes to string
    decodedResult = result.decode("utf-8")
    # parse the string back to an array
    parsedArray = list(map(int, decodedResult.split(" ")))
    print("\ntime: ",time.time()-start)

    # Close socket
    f.close()
    zmq_socket.close()

producer()

C++服務器

#include <zmq.h>
#include <assert.h>
#include <vector>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fstream> // for writing files
#include <iostream>

typedef unsigned char uchar;

using namespace std;
vector<pair<int,int>> arr;

static string base64_decode(const string &in) {
    // Ref: https://stackoverflow.com/a/34571089/9625777
    string out;
    vector<int> T(256,-1);
    for (int i=0; i<64; i++)
        T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;

    int val=0, valb=-8;
    for (uchar c : in) {
        if (T[c] == -1) break;
        val = (val << 6) + T[c];
        valb += 6;
        if (valb >= 0) {
            out.push_back(char((val>>valb)&0xFF));
            valb -= 8;
        }
    }
    return out;
}


int main ()
{
    while(1) // Stay ON eternally
    {
      // Create socket
      void *context = zmq_ctx_new ();
      void *responder = zmq_socket (context, ZMQ_REP);
      int rc = zmq_bind(responder, "tcp://*:5556");
      assert (rc == 0);
      //{
        // The zmq_connect() function returns zero if successful.
        // Otherwise it returns -1
      //}
      cout << "\nGot a connection";

      // Receive data/Request
      char buffer [4194328]; // big enough to accomodate selected image
      auto nbytes = zmq_recv (responder, buffer, 4194328, 0);assert (nbytes != -1);
      cout << "Got a request";
      // Do something with the received image
      // decode data
      auto decodedData = base64_decode(buffer);
      // write results to a file
      ofstream myFile("res.ppm");
      myFile << decodedData;
      myFile.close();

      // Generate dummy reply/response
      int arr[] = { 11, 21, 31, 41 };
      // Encode to a C++ string
      std::string str;
      for (int i: arr) {
          str += std::to_string(i);
          str += " "; //Add whitespace as delimiter
      }

      // Create zmq message envelope reply
      zmq_msg_t msg;
      rc = zmq_msg_init_size (&msg, sizeof(arr));
      assert (rc == 0);

      // Convert c++ type string to C type. ZMQ doesn't allow sending C++ type strings
      char * cstr = new char [str.length()+1];
      strcpy (cstr, str.c_str());
      // cstr now contains a c-string copy of str

      // Send Result/Response
      rc = zmq_send(responder, cstr, sizeof(cstr),0);
      assert(rc != -1);

      // Close socket
      zmq_close (responder);
      zmq_ctx_destroy (context);
    }
    return 0;
}

請注意,zmq 庫是使用sudo apt-get install libzmq3-dev Cpp 腳本必須使用有效的鏈接器標志進行編譯。

$ gcc -Wall -g server.cpp -lzmq -lstdc++ -o server

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM