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
- 开始写.proto文件:
- BaseMessage.proto:
- message MessageBase
- {
- required int32 opcode = 1;
- // other: sendMgrId, sendId, recvMgrId, recvId, ...
- }
- message BaseMessage
- {
- required MessageBase msgbase = 1;
- }
- BaseMessage.proto是其它消息proto文件的基础,以容器模块的C2S_GetContainerInfo为例:
- ContainerMessage.proto:
- import "BaseMessage.proto";
- message C2SGetContainerInfoMsg
- {
- required MessageBase msgbase = 1;
- optional int32 containerType = 2;
- }
- .proto文件编写规则:
- 1)所有消息都需要包含msgbase这项,并编号都为1,即:
- required MessageBase msgbase = 1;
- 2)除了msgbase这项写成required外,其它所有项都写成optional。
- 编译 .proto 文件
- protoc -I=. --cpp_out=. BaseMessage.proto
- protoc -I=. --cpp_out=. ContainerMessage.proto
- 生成BaseMessage.pb.h、BaseMessage.pb.cc
- ContainerMessage.pb.h、ContainerMessage.pb.cc
- 将它们添加到工程文件中。
- 编写C++代码:
- 1)发送消息:
- C2SGetContainerInfoMsg msg;
- msg.mutable_msgbase()->set_opcode(C2S_GetContainerInfo);
- msg.set_containertype(1);
- std::string out = msg.SerializeAsString();
- send(sockfd, out.c_str(), out.size(), 0);
- 2)接收消息
- char buf[MAXBUF + 1];
- int len;
- bzero(buf, MAXBUF + 1);
- len = recv(new_fd, buf, MAXBUF, 0);
- if (len > 0)
- {
- printf("%d接收消息成功:'%s',共%d个字节的数据/n",
- new_fd, buf, len);
- BaseMessage baseMsg;
- std::string data = buf;
- baseMsg.ParseFromString(data);
- int opcode = baseMsg.mutable_msgbase()->opcode();
- printf("opcode=%d/n", opcode);
- switch (opcode)
- {
- case C2S_GetContainerInfo:
- {
- C2SGetContainerInfoMsg msg;
- msg.ParseFromString(data);
- printf("containerType=%d/n", msg.containertype());
- break;
- }
- default:
- {
- break;
- }
- }
- }
- else
- {
- if (len < 0)
- printf("消息接收失败!错误代码是%d,错误信息是'%s'/n",
- errno, strerror(errno));
- close(new_fd);
- return -1;
- }
- 编译C++代码:
- Need to link lib:
- protobuf
- pthread
- 参考:
- 1,http://www.360doc.com/content/10/0822/16/11586_47942017.shtml
- 2,http://code.google.com/p/protobuf/
Server:
- #include "stdafx.h"
- #include <stdio.h>
- #include <Winsock2.h>
- #include <windows.h>
- #include <string>
-
- #include "msg.pb.h"
-
- #pragma comment(lib,"ws2_32.lib")
- #pragma commen (lib,"libprotobuf.lib")
-
- using namespace std;
- int _tmain(int argc, _TCHAR* argv[])
- {
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
-
- wVersionRequested = MAKEWORD(1,1);
- err = WSAStartup(wVersionRequested,&wsaData);
- if ( err != 0)
- return 0;
-
- if ( LOBYTE( wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
- {
- WSACleanup();
- return 0;
- }
-
- SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);
-
- SOCKADDR_IN addrSrv;
- addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
- addrSrv.sin_family = AF_INET;
- addrSrv.sin_port = htons(8000);
-
- bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
- printf("Bind OK...\n");
-
- listen(sockSrv,5);
- printf("Listen OK ...\n");
-
- SOCKADDR_IN addrClient;
- int len = sizeof(SOCKADDR);
-
- while(1)
- {
- SOCKET sockConn = accept(sockSrv,(SOCKADDR*)&addrClient,&len);
- printf("Receive data...\n");
-
- char recvBuf[500];
- memset(recvBuf,0,500);
- recv(sockConn, recvBuf, 500, 0);
-
- test::Vo_CharacterInfo Info;
- Info.ParseFromString(string(recvBuf);
- closesocket(sockConn);
- printf("Close Socket...\n");
- }
-
- system("pause");
- return 0;
- }
Client:
- // Client.cpp : 定义控制台应用程序的入口点。
- //
-
- #include "stdafx.h"
- #include "msg.pb.h"
- #include <stdio.h>
- #include <windows.h>
- #include <fstream>
- #include <string>
-
- #pragma comment(lib,"ws2_32.lib")
- #pragma comment(lib,"libprotobuf.lib")
-
- using namespace std;
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
- wVersionRequested = MAKEWORD(1,1);
-
- err = WSAStartup( wVersionRequested, &wsaData);
- if ( err != 0)
- {
- return 0;
- }
- if ( LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion != 1))
- {
- WSACleanup();
- return 0;
- }
-
- SOCKET sockClient = socket(AF_INET,SOCK_STREAM,0);
-
- SOCKADDR_IN addrSrv;
- addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
- addrSrv.sin_family = AF_INET;
- addrSrv.sin_port = htons(8000);
-
- connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
- printf("Connect Successful...\n");
-
test::Vo_CharacterInfo Info;
Info.set_charid(123);
- 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;
- }