python 和 c++ 之间发消息用json
来源:互联网 发布:淘宝 买家秀图 编辑:程序博客网 时间:2024/05/31 15:19
这段代码是py发给c++的一个消息包,包里含json字符串,没有c++返回的过程!
-------------------
因为工作需要...中间省略5000字,所以用c++做的服务器,收发消息需要用json来打包并解析消息。
我以前收发消息都是结构体直接强转,所以这也是第一次,发个帖子上来,希望对有的朋友有帮助。
-------------------
先说python,这个语言一直想学,这段时间学了个把星期,发现测试的确非常方便,总比用c++写测试代码好多了,用c++写测试代码的那个蛋疼,py几行代码就搞到了。
准备发上py代码,这之前先做一个大概的说明,这段py代码不是纯粹的发一条json消息,还附带了一个简单的tcp socket的并发连接测试代码,也就是创建N个线程去connect服务器,不需要的自己过滤吧。这段代码用了py的那个好像叫装饰器的东西,就是@这个,不明白的朋友可以百度,简单的来说,我的这个装饰器就是用来统计时间的。
__author__ = 'Administrator'import socketimport jsonimport threadingimport datetimeimport structdef get_execute_time_p2(f): def inner(p1=None, p2=None): begin = datetime.datetime.now().microsecond f(p1, p2) end = datetime.datetime.now().microsecond print("{0} execute time is {1}".format(f.__name__, end-begin)) return f return innerdef get_execute_time_p1(f): def inner(p1=None): begin = datetime.datetime.now().microsecond f(p1) end = datetime.datetime.now().microsecond print("{0} execute time is {1}".format(f.__name__, end-begin)) return f return innerdef get_socket(): host = "localhost" port = 8001 address = (host, port) tcp_socket_temp = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_socket_temp.settimeout(2) tcp_socket_temp.connect(address) return tcp_socket_temp@get_execute_time_p1def test_accept(cnt): print("thread launched.") ok__ = 0 for xer34 in range(cnt): try: sd2342 = get_socket() # input("enter any key to continue...") sd2342.close() ok__ += 1 # print(xer34, end=" ") # if xer34 % 30 == 0: # print("") # C R L F except Exception as e: print(e) print("connect svr success cnt is {0}".format(ok__))@get_execute_time_p2def create_thread_to_test_accept(thread_count, con_cnt_every_thread): for x342df in range(thread_count): thread = threading.Thread(None, test_accept, "test_accept", (con_cnt_every_thread,)) thread.start()def print_binary(number): for sda24 in range(32): if number & (1 << sda24): print(1, end="") else: print(0, end="") if (sda24 + 1) % 8 == 0: print(" ", end="")data_list_child = []for cnt in range(3): data_list_child.append({"_f": 123.123, "_long_id": "1234567890123456789"})data_list = {"_msg_enum": 0, "_buffer": "abcdefg", "_element_len": 3, "_element": data_list_child}data_json = json.dumps(data_list)print(data_list)print(len(data_json), data_json)# use 4 threads and every thread executes 10000 connections test to connect svr# test OK!# create_thread_to_test_accept(4, 50000)my_fmt = "i{0}s".format(len(data_json))print(my_fmt)send_string = struct.pack(my_fmt, 4 + len(data_json), bytes(data_json, "utf8"))print(send_string, type(send_string))a1, a2 = struct.unpack(my_fmt, send_string)print(a1, a2)tmp_socket = get_socket()tmp_socket.send(send_string)input("enter 'enter' to close socket and quit.")tmp_socket.close()
使用的py3,运行结果差点忘记了,如下:
E:\Python34\python.exe E:/PycharmProjects/study/resource-svr-test.py
{'_msg_enum': 0, '_element_len': 3, '_buffer': 'abcdefg', '_element': [{'_long_id': '1234567890123456789', '_f': 123.123}, {'_long_id': '1234567890123456789', '_f': 123.123}, {'_long_id': '1234567890123456789', '_f': 123.123}]}
227 {"_msg_enum": 0, "_element_len": 3, "_buffer": "abcdefg", "_element": [{"_long_id": "1234567890123456789", "_f": 123.123}, {"_long_id": "1234567890123456789", "_f": 123.123}, {"_long_id": "1234567890123456789", "_f": 123.123}]}
i227s
b'\xe7\x00\x00\x00{"_msg_enum": 0, "_element_len": 3, "_buffer": "abcdefg", "_element": [{"_long_id": "1234567890123456789", "_f": 123.123}, {"_long_id": "1234567890123456789", "_f": 123.123}, {"_long_id": "1234567890123456789", "_f": 123.123}]}' <class 'bytes'>
231 b'{"_msg_enum": 0, "_element_len": 3, "_buffer": "abcdefg", "_element": [{"_long_id": "1234567890123456789", "_f": 123.123}, {"_long_id": "1234567890123456789", "_f": 123.123}, {"_long_id": "1234567890123456789", "_f": 123.123}]}'
enter 'enter' to close socket and quit.
Process finished with exit code 0
或许你看到了在大括号“{”前面的227,这个227是一个完整的消息包的一部分,但是不属于json的一部分,这个227表示整个包的大小,做tcp socket的应该都知道,这个协议收到的包是要自己拆粘的。包的格式是:{int, char[]}。
-----------------
以上py的已经说完了,下面说c++的代码,c++用的jsoncpp解析的,这个使用非常简单,这里只传上解析的过程, 因为c++的代码太多.下面第一部分代码是从消息包里解析出json,1:
static Json::Reader _g_this_reader;void DoClientReq::Do(__cr_phd_ptr phd){/* 包头定义包的长度,该定义不属于json需要解析的范围 */Json::Value value;char* buffer = phd->_buffer.Get() + HEADSIZE;_g_this_reader.parse(buffer, buffer + phd->_offset, value);do_client_req(value);}第二部分是获取json里的内容,内容涵盖了int, int64, float/double, char[], 以及结构体里的数组信息等:
void DoClientReq::do_client_req(const Json::Value& value){if (value.empty() || !value.isMember("_msg_enum")){return;}eProtocol e = (eProtocol)value["_msg_enum"].asInt();switch (e){case eProtocol::_req_test:/* 227 {"_buffer": "abcdefg", "_element_len": 3, "_msg_enum": 0, "_element": [{"_f": 123.123, "_long_id": "1234567890123456789"}, {"_f": 123.123, "_long_id": "1234567890123456789"}, {"_f": 123.123, "_long_id": "1234567890123456789"}]} *//* *227 *{"_buffer": "abcdefg", "_element_len": 3, "_msg_enum": 0, *"_element": \ *[{"_f": 123.123, "_long_id": "1234567890123456789"}, *{"_f": 123.123, "_long_id": "1234567890123456789"}, *{"_f": 123.123, "_long_id": "1234567890123456789"}]} */{printf("\n-------------------JSON TEST BEGIN-----------------------------\n");printf("_msg_enum(int):%d\n", value["_msg_enum"].asInt());printf("_buffer(char[]):%s\n", value["_buffer"].asCString());printf("_element_len(int):%d\n", value["_element_len"].asInt());Json::Value child = value["_element"];for (int i = 0; i < value["_element_len"].asInt(); i++){printf("_element(array):\n");printf("\t_element::_long_id(int64):%lld\n", _atoi64(child[i]["_long_id"].asCString()));printf("\t_element::_f(double/float):%f\n", child[i]["_f"].asDouble());}printf("-------------------JSON TEST END-------------------------------\n");}break;default:break;}}
下面附上c++解析的结果:
-------------------JSON TEST BEGIN-----------------------------
_msg_enum(int): 0
_buffer(char[]): abcdefg
_element_len(int): 3
_element(array):
_element::_long_id(int64): 1234567890123456789
_element::_f(double/float): 123.123000
_element(array):
_element::_long_id(int64): 1234567890123456789
_element::_f(double/float): 123.123000
_element(array):
_element::_long_id(int64): 1234567890123456789
_element::_f(double/float): 123.123000
-------------------JSON TEST END-------------------------------
如果去掉最后一个0,则解析成功,难道19位数字是有符号int64的最大数字长度?如果有朋友了解,麻烦回复下,谢谢!以便我日后参考以及留给他人。
- python 和 c++ 之间发消息用json
- 对话框之间发消息
- 通过python和xmpp模拟用户发消息
- 用python给微信公众号发消息
- activeMQ发消息和接收消息
- 【Python开发】C和Python之间的接口实现
- json-c发segmentation fault问题
- tcp客户端和服务端互发消息
- 用Python发邮件
- 用python发邮件
- 用Python发电子邮件
- 发消息
- 关于C和Python之间通信的方法
- 关于C和Python之间通信的方法
- Python和C/C++之间数据转换的代码
- 利用thrift在c++、java和python之间相互调用
- 利用thrift在c++、java和python之间相互调用
- Swig—C/C++和Python之间的粘结剂
- UVA201 - Squares
- c++实现Callback机制
- Java基础----UDP
- h2database源码浅析:SQL语句的执行
- 变量类型 15-1-2
- python 和 c++ 之间发消息用json
- 《gdb调试之基础篇》
- MongoDB学习笔记(四) 用MongoDB的文档结构描述数据关系
- 学习->linux多线程网址
- iOS CoreData的基本使用
- MongoDB学习笔记(五) MongoDB文件存取操作
- day13_多线程
- 简单的ant打包,修改渠道号
- UVA 299- Train Swapping(冒泡排序中交换次数)