linux下安装protobuf教程+示例

来源:互联网 发布:笛卡尔的方法论知乎 编辑:程序博客网 时间:2024/05/19 19:16
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);
          Info.set_charname("name");

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


  3.     send(sockClient, info.data(), info.size(),0);
  4.     printf("Send Successful...\n");
  5.    

  6.     closesocket(sockClient);
  7.     WSACleanup();

  8.     system("pause");
  9.     return 0;
  10. }

原创粉丝点击