加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 前言
    • nanomsg簡(jiǎn)介
    • nanomsg編譯/交叉編譯
    •  
    • nanomsg使用例子
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

實(shí)用 | 一個(gè)高性能通信庫(kù)的簡(jiǎn)單使用分享

2021/03/22
315
閱讀需 7 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

前言

上次的推文實(shí)用 | 分享幾個(gè)非常實(shí)用的開源項(xiàng)目中有提到過(guò)nanomsg,正好最近的工作中也有用到nanomsg,本篇推文來(lái)簡(jiǎn)單分享一下nanomsg的基本使用。

nanomsg簡(jiǎn)介

nanomsg是一個(gè)實(shí)現(xiàn)了幾種可擴(kuò)展協(xié)議的高性能通信庫(kù);可擴(kuò)展協(xié)議的任務(wù)是定義多個(gè)應(yīng)用系統(tǒng)如何通信,從而組成一個(gè)大的分布式系統(tǒng)。

下載鏈接:

https://github.com/gaobaoru/nanomsg/

當(dāng)前版本nanomsg支持以下協(xié)議:

  • 配對(duì)模式:簡(jiǎn)單的一對(duì)一的通信;總線模式:簡(jiǎn)單的多對(duì)多的通信;請(qǐng)求/回復(fù)模式:支持組建大規(guī)模的集群服務(wù)來(lái)處理用戶請(qǐng)求;扇入模式:支持從多個(gè)源聚合請(qǐng)求消息;扇出模式:支持分配到多個(gè)節(jié)點(diǎn)以支持負(fù)載均衡;調(diào)查模式:允許在一個(gè)單一的請(qǐng)求里檢查多個(gè)應(yīng)用的狀態(tài);

可擴(kuò)展協(xié)議是在網(wǎng)絡(luò)通信協(xié)議之上實(shí)現(xiàn)的,當(dāng)前版本nanomsg支持一下網(wǎng)絡(luò)協(xié)議

  • INPROC:?jiǎn)芜M(jìn)程內(nèi)通信;IPC:?jiǎn)螜C(jī)內(nèi)多進(jìn)程的通信;TCP:通過(guò)tcp協(xié)議的網(wǎng)絡(luò)通信;

nanomsg用c實(shí)現(xiàn),不依賴系統(tǒng)特性,所以支持多個(gè)操作系統(tǒng)。

nanomsg編譯/交叉編譯

按照上面的鏈接下載后的到:

首先創(chuàng)建一個(gè)build文件夾用于管理我們編譯所需、編譯生成的一些文件。

這里,我們演示編譯/交叉編譯,首先在build目錄下分別創(chuàng)建如下兩個(gè)文件夾存放我們待會(huì)編譯得到的x86_lib、arm_lib:

然后在build路徑下根據(jù)自己的需要輸入如下命令生成Makefile、進(jìn)行編譯/交叉編譯、測(cè)試:

1、編譯

① cmake .. -DCMAKE_INSTALL_PREFIX=$PWD/nanomsg_x86_lib
② cmake --build .
③ ctest .
④ sudo cmake --build . --target install
⑤ sudo ldconfig

① :/usr/local/ 是默認(rèn)安裝到的根目錄,可以通過(guò)修改 CMAKE_INSTALL_PREFIX 變量的值來(lái)指定這些文件應(yīng)該拷貝到哪個(gè)目錄,這里我們指定到當(dāng)前目錄的nanomsg_x86_lib目錄。

② :編譯。

③ :測(cè)試。CMake 提供了一個(gè)稱為 CTest 的測(cè)試工具,nanomsg項(xiàng)目根目錄的 CMakeLists 文件中調(diào)用了 add_test 命令進(jìn)行測(cè)試。

④ :安裝。把編譯生成的庫(kù)及相關(guān)頭文件安裝到nanomsg_x86_lib目錄中。

⑤ :讓生成的nanomsg動(dòng)態(tài)鏈接庫(kù)為系統(tǒng)所共享。ldconfig是一個(gè)動(dòng)態(tài)鏈接庫(kù)管理命令,其目的為了讓動(dòng)態(tài)鏈接庫(kù)為系統(tǒng)所共享。

查看生成的動(dòng)態(tài)庫(kù)是否是x86架構(gòu)的:

2、交叉編譯

在nanomsg根目錄下的CMakeLists.txt文件里加上交叉編譯器設(shè)置:

然后輸入如下命令:

① cmake .. -DCMAKE_INSTALL_PREFIX=$PWD/nanomsg_arm_lib
② cmake --build .
③ sudo cmake --build . --target install
④ sudo ldconfig

與上面的編譯x86的nanomsg 庫(kù)的步驟差不多,這里把測(cè)試的指令ctest .去掉了,因?yàn)樯傻目蓤?zhí)行文件是arm架構(gòu)的,所以直接運(yùn)行測(cè)試會(huì)出錯(cuò)。

查看生成的動(dòng)態(tài)庫(kù)是否是arm架構(gòu)的:

 

nanomsg使用例子

nanomsg可用于多線程、多進(jìn)程、多機(jī)通信。nanomsg是一個(gè)socket library,所以其應(yīng)用接口與標(biāo)準(zhǔn)的socket接口差不多,只是多了前綴nn_,如nn_socket、nn_close、nn_send、nn_recv等。關(guān)于socket可查閱往期筆記:

【socket筆記】TCP、UDP通信總結(jié)

【socket應(yīng)用】基于C語(yǔ)言的天氣客戶端的實(shí)現(xiàn)

下面演示進(jìn)程間通信的client-server的例子,以下測(cè)試代碼主要實(shí)現(xiàn)的是client-server進(jìn)行收發(fā)測(cè)試。

nanomsg_server.c:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define BUF_LEN  100

char *url = "tcp://127.0.0.1:2021";

int main(void)
{
 int server_sock = 0;
 char buf[BUF_LEN] = {0};

 if (server_sock = nn_socket (AF_SP, NN_PAIR) < 0)
 {
  printf("create server socket failed!n");
  return -1;
 }
 
 if (nn_bind(server_sock, url) < 0) 
 {
  printf("bind server sock failed!rn");
  nn_close(server_sock);
  return -1;
 }
 printf("server init success!n");

 while (1)
 {
  if (nn_recv(server_sock, buf, sizeof(buf), 0) < 0) 
  {
   printf("recv failed!n");
   nn_close(server_sock);
   exit(EXIT_FAILURE);
  }
  else
  {
   printf("recieve client msg: %srn", buf);
   if (nn_send(server_sock, buf, sizeof(buf), 0) < 0)
   {
    printf("send failed!rn");
    nn_close(server_sock);
    exit(EXIT_FAILURE);
   }
  }
 }

 nn_close(server_sock);

 return 0;
}

nanomsg_client.c:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define BUF_LEN  100

char *url = "tcp://127.0.0.1:2021";

int main(void)
{
 int client_sock = 0;
 char buf[BUF_LEN] = {0};

 if (client_sock = nn_socket (AF_SP, NN_PAIR) < 0)
 {
  printf("create server socket failed!n");
  return -1;
 }

 if (nn_connect(client_sock, url) < 0) 
 {
  printf("connect server sock failed!rn");
  nn_close(client_sock);
  return -1;
 }

 printf("client init success!n");

 while (1)
 {
        scanf("%s", buf);
  if (nn_send(client_sock, buf, sizeof(buf), 0) < 0)
  {
   printf("send failed!rn");
   nn_close(client_sock);
  }

        memset(buf, 0, BUF_LEN);   

  if (nn_recv(client_sock, buf, sizeof(buf), 0) > 0) 
  {
   printf("recieve server msg: %srn", buf);
  }
        memset(buf, 0, BUF_LEN);   
 }

 nn_close(client_sock);

 return 0;
}

編譯:

gcc nanomsg_server.c -o nanomsg_server -I /home/book/git_clone/nanomsg/build/nanomsg_x86_lib/include -L /home/book/git_clone/nanomsg/build/nanomsg_x86_lib/lib -lnanomsg
gcc nanomsg_client.c -o nanomsg_client -I /home/book/git_clone/nanomsg/build/nanomsg_x86_lib/include -L /home/book/git_clone/nanomsg/build/nanomsg_x86_lib/lib -lnanomsg

-I xxx:指定頭文件路徑。

-L xxx:指定庫(kù)路徑。

-lnanomsg:鏈接動(dòng)態(tài)庫(kù)nanomsg.so。

運(yùn)行測(cè)試:

運(yùn)行可能會(huì)出現(xiàn)如下錯(cuò)誤:

不能找到共享庫(kù)文件libtest_d.so,加載失敗。因?yàn)橐话闱闆r下Linux會(huì)在/usr/lib路徑中搜索需要用到的庫(kù),而libtest_d.so庫(kù)并不在這個(gè)路徑下。

解決方法有兩種:一種就是把這個(gè)文件拷貝至/usr/lib路徑下,但是一般不允許這樣做,一般用戶也不允許往這個(gè)路徑里拷貝東西。另一種就是把當(dāng)前路徑增加為動(dòng)態(tài)庫(kù)的搜索路徑,命令如:

export LD_LIBRARY_PATH=/home/book/git_clone/nanomsg/build/nanomsg_x86_lib/lib:$LD_LIBRARY_PATH

然后繼續(xù)運(yùn)行:

可見,收發(fā)測(cè)試成功。以上就是本次關(guān)于nanomsg的簡(jiǎn)單使用分享,希望能對(duì)大家有幫助。

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

本公眾號(hào)專注于嵌入式技術(shù),包括但不限于C/C++、嵌入式、物聯(lián)網(wǎng)、Linux等編程學(xué)習(xí)筆記,同時(shí),公眾號(hào)內(nèi)包含大量的學(xué)習(xí)資源。歡迎關(guān)注,一同交流學(xué)習(xí),共同進(jìn)步!