firefly学习笔记之C客户端与Python服务器交互(3)
来源:互联网 发布:js获取application值 编辑:程序博客网 时间:2024/06/05 05:52
这一章介绍现在比较流行的通信格式Protocol Buffer。
4.PB (Protocol Buffer解析)
ProtocolBuffer是用于结构化数据串行化的灵活,高效,自动的方法,有如XML,JSON.不过它更小,更快,也更简单,你可以定义自 己的数据机构,然后使用代码生成器生成的代码来读写这个数据结构。不过注意一下,protocol buffer的proto文件你要是用string类型,那么你在c++中用的是utf-8,在java和python中必须用unicode。
teststruct.proto
option optimize_for = LITE_RUNTIME; //最优编码message Person { required string name = 1; //用户名 required int32 id = 2; //用户id optional string email = 3; //email //号码类型枚举 enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber {
required string number = 1; //号码 optional PhoneType type = 2 [default = HOME]; //号码类型 } required int32 phonecnt = 4;//号码数量 repeated PhoneNumber phone = 5; //号码[packed=true]用于优化,只能用于原始的几个类型} message AddressBook { required int32 personcnt = 1;//玩家数量 repeated Person person = 2; //玩家信息
}
client.cpp
// testPython2.cpp : Defines the entry point for the console application.//// testpython.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <Windows.h>#include <string>#include "teststruct.pb.h"using namespace std;#pragma comment(lib,"ws2_32.lib")#pragma pack(push)#pragma pack(1)struct sTest{int id;char szName[10];};#pragma pack(pop)//iconv也行string Utf8ToGBK(string str){...
}string GBKToUTF8(string str){
...}string ConvertAddressBookToString(){//转换pbtostringAddressBook addressbook;addressbook.set_personcnt(2);//repeat 对象,数组addPerson *pInfo1 = addressbook.add_person();pInfo1->set_id(111);pInfo1->set_name(GBKToUTF8("天下").c_str());pInfo1->set_email("xx@163.com");pInfo1->set_phonecnt(2);//repeat数组Person_PhoneNumber*pNumber1 = pInfo1->add_phone();pNumber1->set_type(Person_PhoneType_HOME);pNumber1->set_number("187XXXXXX");pNumber1 = pInfo1->add_phone();pNumber1->set_type(Person_PhoneType_MOBILE);pNumber1->set_number("178XXXXX");pInfo1 = addressbook.add_person();pInfo1->set_id(112);pInfo1->set_name(GBKToUTF8("天下x").c_str());pInfo1->set_email("xxx@163.com");pInfo1->set_phonecnt(1);//repeat数组pNumber1 = pInfo1->add_phone();pNumber1->set_type(Person_PhoneType_HOME);pNumber1->set_number("1587XXXXXX");string str;addressbook.SerializeToString(&str);return str;}void ConvertStringToPB(char* str,int size){AddressBook address;address.ParseFromArray(str,size);//解析printf("address person cnt :%d\n",address.personcnt());printf("______________________________person data_______________________\n");//repeat指针访问//RepeatedPtrField<Person*> *pPersonInfo = address.mutable_person();////if (pPersonInfo == NULL)//return;//RepeatedPtrField<Person*>::iterator it = pPersonInfo->begin();//while(it != pPersonInfo->end());//{//printf("person id:%d\n",it->id());//printf("person name:%s\n",it->name().c_str());//if (it->has_email())//{//printf("person email:%s\n",it->email().c_str());//}//printf("person numbercnt:%d\n",id->phonecnt());//RepeatedPtrField<Person_PhoneNumber*> *pPhone = id->mut//}for (int i = 0 ; i < address.personcnt();++i){Person *pPersonInfo = address.mutable_person(i);if (pPersonInfo){printf("person id:%d\n",pPersonInfo->id());printf("person name:%s\n",Utf8ToGBK(pPersonInfo->name().c_str()).c_str());if (pPersonInfo->has_email()){printf("person email:%s\n",pPersonInfo->email().c_str());}printf("person number cnt:%d\n",pPersonInfo->phonecnt());printf("______________________________phone data_______________________\n");for (int j = 0; j < pPersonInfo->phonecnt();++j){Person_PhoneNumber *pNumber = pPersonInfo->mutable_phone(j);if (pNumber){printf("person phone number:%s\n",pNumber->number().c_str());printf("person phone type:%d\n",pNumber->type());}}printf("______________________________phone data_______________________\n");}}printf("______________________________person data_______________________\n");}int _tmain(int argc, _TCHAR* argv[]){WSADATA wd;WSAStartup(MAKEWORD(2,2),&wd);SOCKET client = socket(AF_INET,SOCK_STREAM,0);if (client == SOCKET_ERROR){printf("error:%d\n",WSAGetLastError());exit(0);}SOCKADDR_IN addr;addr.sin_family = AF_INET;addr.sin_port = htons(8877);addr.sin_addr.s_addr = inet_addr("127.0.0.1");int ret = connect(client,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));if (ret != 0){printf("error:%d\n",WSAGetLastError());exit(0);}string str = ConvertAddressBookToString();printf("%s\n",str.c_str());int sendsize = send(client,str.c_str(),str.length(),0);if (sendsize == 0){printf("error:%d\n",WSAGetLastError());exit(0);}char szBuf[1024] = {0};int recvdata = recv(client,szBuf,1024,0);szBuf[recvdata] = '\0';printf("recvdata:%d\n",recvdata);ConvertStringToPB(szBuf,recvdata-1);WSACleanup();system("pause");return 0;}
python server.py
#coding:utf8'''@author: Administrator'''import teststruct_pb2;import socket;import sys;#datatopbdef PaseStringToPB(data): address = teststruct_pb2.AddressBook(); address.ParseFromString(data); cnt = address.personcnt; print "number of person:%d"%(cnt); #循环每个玩家 for person in address.person: print "person id:",person.id; print "person name:",person.name; #optional不一定存在 if person.HasField("email"): print "person name email:",person.email; print "person has number cnt:",person.phonecnt; #循环遍历每一个phone for phone in person.phone: if phone.type == teststruct_pb2.Person.MOBILE: print "person phone type: MOBILE"; elif phone.type == teststruct_pb2.Person.WORK: print "person phone type: WORK"; elif phone.type == teststruct_pb2.Person.HOME: print "person phone type: HOME"; else: print "person phone tpye: NONE"; print "person phone number:",phone.number; if __name__ == "__main__": host = "127.0.0.1"; port = 8877; addr = (host,port); #socket created try: server = socket.socket(socket.AF_INET,socket.SOCK_STREAM); except socket.error,msg: print "socket created failed ! errno:" + str(msg[0]) + " errmsg:" + str(msg[1]); sys.exit(); else: print "socket create sucesss!"; #bind try: server.bind(addr); except socket.error,msg: print "socket bind failed ! errno:" + str(msg[0]) + " errmsg:" + str(msg[1]); sys.exit(); else: print "socket bind success!"; #listen server.listen(10); while True: client,caddr = server.accept(); print caddr; recvdata = client.recv(1024); #string to pb PaseStringToPB(recvdata); #pbtostring address = teststruct_pb2.AddressBook(); address.personcnt = 2; #repeat add 类似一个数组 person1 = address.person.add(); person1.id = 123; namestr = "张三"; person1.name = namestr.decode("utf-8"); person1.email = "111@163.com"; person1.phonecnt = 1; phone1 = person1.phone.add(); phone1.type = teststruct_pb2.Person.MOBILE; phone1.number = "187XXXXXXX"; person2 = address.person.add(); person2.id = 123; namestr = "李四"; person2.name = namestr.decode("utf-8"); person2.email = "111@163.com"; person2.phonecnt = 1; phone2 = person2.phone.add(); phone2.type = teststruct_pb2.Person.WORK; phone2.number = "187XXXXXXX"; ##序列化 message = address.SerializeToString(); print message; client.sendall(message); print len(message); client.close(); server.close();
几种常用的通信格式都介绍完,在后面的firefly练习中,也会用赶流行的用PB,来作为数据交互格式!
0 0
- firefly学习笔记之C客户端与Python服务器交互(3)
- firefly学习笔记之C客户端与Python服务器交互(1)
- firefly学习笔记之C客户端与Python服务器交互(2)
- firefly笔记之python socket
- android服务器与客户端交互之servlet
- node.js学习笔记之创建UDP服务器与客户端
- android客户端 与服务器交互
- fms 服务器与客户端交互
- Android 客户端与服务器交互
- 客户端与服务器的交互
- HLS协议之服务器与客户端之前的交互流程
- HLS协议之服务器与客户端之前的交互流程
- python与c语言交互---学习012
- lua 与 C交互 学习笔记
- FireFly开发之路(一)python学习一
- FireFly开发之路(二)python学习二
- java socket-3--多客户端与服务器的交互
- FireFly菜鸟学习二(cocos2dx客户端和服务器通信实现)
- Android布局一_RelativeLayout
- Sap软件开发职位面试全过程
- Codeforces Round #234 (Div. 2) :A. Inna and Choose Options
- Hibernate持久化对象生命周期之实战探索
- 数据库新技术发展时间轴(1994-2014)
- firefly学习笔记之C客户端与Python服务器交互(3)
- 系统的对单机版hadoop进行配置和安装,调试!!!
- hexo博客的优化与配置——添加统计代码
- 走地板 深搜基础
- mysql5.5异常: java.sql.SQLException: Packet for query is too large (1055975 > 1048576).
- linux,apache,php,mysql常用的查看版本信息的方法
- 【leetcode】Candy(python)
- sgu112 高精度大整数乘方
- Java hashCode 和 equals 方法