linux下安裝protobuf教程+示例

工程師WWW發表於2013-10-23
1 在網站 http://code.google.com/p/protobuf/downloads/list上可以下載 Protobuf 的原始碼。然後解壓編譯安裝便可以使用它了。
安裝步驟如下所示:
 tar -xzf protobuf-2.1.0.tar.gz 
 cd protobuf-2.1.0 
 ./configure --prefix=/usr/local/protobuf
 make 
 make check 
 make install 
 
 2 > sudo vim /etc/profile
新增
export PATH=$PATH:/usr/local/protobuf/bin/
export PKG_CONFIG_PATH=/usr/local/protobuf/lib/pkgconfig/

儲存執行
source /etc/profile

同時 在~/.profile中新增上面兩行程式碼,否則會出現登入使用者找不到protoc命令

3 > 配置動態連結庫路徑
sudo vim /etc/ld.so.conf
插入:
/usr/local/protobuf/lib

4 > su  #root 許可權
ldconfig

  1. 開始寫.proto檔案:  
  2. BaseMessage.proto:  
  3. message MessageBase  
  4. {  
  5.     required int32 opcode = 1;  
  6.     // other: sendMgrId, sendId, recvMgrId, recvId, ...  
  7. }  
  8.   
  9. message BaseMessage  
  10. {  
  11.     required MessageBase msgbase = 1;  
  12. }  
  13.   
  14. BaseMessage.proto是其它訊息proto檔案的基礎,以容器模組的C2S_GetContainerInfo為例:  
  15. ContainerMessage.proto:  
  16. import "BaseMessage.proto";  
  17.   
  18. message C2SGetContainerInfoMsg  
  19. {  
  20.     required MessageBase msgbase = 1;  
  21.     optional int32 containerType = 2;  
  22. }  
  23.   
  24. .proto檔案編寫規則:  
  25. 1)所有訊息都需要包含msgbase這項,並編號都為1,即:  
  26.   required MessageBase msgbase = 1;  
  27. 2)除了msgbase這項寫成required外,其它所有項都寫成optional。  
  28.   
  29. 編譯 .proto 檔案  
  30. protoc -I=. --cpp_out=. BaseMessage.proto  
  31. protoc -I=. --cpp_out=. ContainerMessage.proto  
  32. 生成BaseMessage.pb.h、BaseMessage.pb.cc  
  33.     ContainerMessage.pb.h、ContainerMessage.pb.cc  
  34. 將它們新增到工程檔案中。  
  35.   
  36. 編寫C++程式碼:  
  37. 1)傳送訊息:  
  38. C2SGetContainerInfoMsg msg;  
  39. msg.mutable_msgbase()->set_opcode(C2S_GetContainerInfo);  
  40. msg.set_containertype(1);  
  41. std::string out = msg.SerializeAsString();  
  42. send(sockfd, out.c_str(), out.size(), 0);  
  43. 2)接收訊息  
  44. char buf[MAXBUF + 1];  
  45. int len;  
  46. bzero(buf, MAXBUF + 1);  
  47. len = recv(new_fd, buf, MAXBUF, 0);  
  48. if (len > 0)  
  49. {  
  50.     printf("%d接收訊息成功:'%s',共%d個位元組的資料/n",  
  51.             new_fd, buf, len);  
  52.   
  53.     BaseMessage baseMsg;  
  54.     std::string data = buf;  
  55.     baseMsg.ParseFromString(data);  
  56.   
  57.     int opcode = baseMsg.mutable_msgbase()->opcode();  
  58.   
  59.     printf("opcode=%d/n", opcode);  
  60.   
  61.     switch (opcode)  
  62.     {  
  63.     case C2S_GetContainerInfo:  
  64.     {  
  65.         C2SGetContainerInfoMsg msg;  
  66.         msg.ParseFromString(data);  
  67.   
  68.         printf("containerType=%d/n", msg.containertype());  
  69.   
  70.         break;  
  71.     }  
  72.     default:  
  73.     {  
  74.         break;  
  75.     }  
  76.     }  
  77. }  
  78. else  
  79. {  
  80.     if (len < 0)  
  81.         printf("訊息接收失敗!錯誤程式碼是%d,錯誤資訊是'%s'/n",  
  82.              errno, strerror(errno));  
  83.     close(new_fd);  
  84.     return -1;  
  85. }  
  86.   
  87.   
  88. 編譯C++程式碼:  
  89. Need to link lib:  
  90. protobuf  
  91. pthread  
  92.   
  93.   
  94. 參考:   
  95. 1,http://www.360doc.com/content/10/0822/16/11586_47942017.shtml  
  96. 2,http://code.google.com/p/protobuf/  
  97.   

Server:
  1. #include "stdafx.h"
  2. #include <stdio.h>
  3. #include <Winsock2.h>
  4. #include <windows.h>
  5. #include <string>

  6. #include "msg.pb.h"

  7. #pragma comment(lib,"ws2_32.lib")
  8. #pragma commen (lib,"libprotobuf.lib")

  9. using namespace std;
  10. int _tmain(int argc, _TCHAR* argv[])
  11. {
  12.     WORD wVersionRequested;
  13.     WSADATA wsaData;
  14.     int err;

  15.     wVersionRequested = MAKEWORD(1,1);
  16.     err = WSAStartup(wVersionRequested,&wsaData);
  17.     if ( err != 0)
  18.         return 0;
  19.     
  20.     if ( LOBYTE( wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
  21.     {
  22.         WSACleanup();
  23.         return 0;
  24.     }
  25.     
  26.     SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);

  27.     SOCKADDR_IN addrSrv;
  28.     addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
  29.     addrSrv.sin_family = AF_INET;
  30.     addrSrv.sin_port = htons(8000);

  31.     bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
  32.     printf("Bind OK...\n");

  33.     listen(sockSrv,5);
  34.     printf("Listen OK ...\n");

  35.     SOCKADDR_IN addrClient;
  36.     int len = sizeof(SOCKADDR);

  37.     while(1)
  38.     {
  39.         SOCKET sockConn = accept(sockSrv,(SOCKADDR*)&addrClient,&len);
  40.         printf("Receive data...\n");
  41.         
  42.         char recvBuf[500];
  43.         memset(recvBuf,0,500);       
  44.         recv(sockConn, recvBuf, 500, 0);
  45.   
  46.         test::Vo_CharacterInfo Info;
  47.         Info.ParseFromString(string(recvBuf);
  48.         closesocket(sockConn);
  49.         printf("Close Socket...\n");
  50.     }

  51.     system("pause");
  52.     return 0;
  53. }

Client:

  1. // Client.cpp : 定義控制檯應用程式的入口點。
  2. //

  3. #include "stdafx.h"
  4. #include "msg.pb.h"
  5. #include <stdio.h>
  6. #include <windows.h>
  7. #include <fstream>
  8. #include <string>

  9. #pragma comment(lib,"ws2_32.lib")
  10. #pragma comment(lib,"libprotobuf.lib")

  11. using namespace std;

  12. int _tmain(int argc, _TCHAR* argv[])
  13. {
  14.     WORD wVersionRequested;
  15.     WSADATA wsaData;
  16.     int err;
  17.     wVersionRequested = MAKEWORD(1,1);

  18.     err = WSAStartup( wVersionRequested, &wsaData);
  19.     if ( err != 0)
  20.     {
  21.         return 0;
  22.     }
  23.     if ( LOBYTE(wsaData.wVersion)!=|| HIBYTE(wsaData.wVersion != 1))
  24.     {
  25.         WSACleanup();
  26.         return 0;
  27.     }

  28.     SOCKET sockClient = socket(AF_INET,SOCK_STREAM,0);

  29.     SOCKADDR_IN addrSrv;
  30.     addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
  31.     addrSrv.sin_family = AF_INET;
  32.     addrSrv.sin_port = htons(8000);
  33.     
  34.     connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
  35.     printf("Connect Successful...\n");

  36.       test::Vo_CharacterInfo Info;
          Info.set_charid(123);
  1.       Info.set_charname("name");

    std::string info;
    Info.SerializeToString(&info);


    send(sockClient, info.data(), info.size(),0);
    printf("Send Successful...\n");
   
    closesocket(sockClient);
    WSACleanup();

    system("pause");
    return 0;
}

相關文章