Linux网络序列化与反序列化
Linux网络序列化与反序列化
1. 前言
在网络通信中,互相通信的信息不一定都是字符串,往往一些结构化的信息也需要进行通信。理论上,只要服务器和客户端都自定义一个共同的协议,结构化的信息也能实现正常通信。但考虑到不同系统、不同版本的维护成本,网络通信一般不采取这种方式,而是将结构化的信息变成字符串堆在一起,称为序列化。将序列化的数据通过网络协议各层传输到另一端再对这个字符串进行拆分解析,称为反序列化。
使用系统调用接口进行网络通信时,不需要考虑数据碰撞。因为一个sockfd,代表一个链接,一个链接有两个缓冲区。系统调用的读写本质都是向TCP协议中的发送缓冲区和接受缓冲区拷贝数据,由于发送和接受的缓冲区不同,也就不用考虑同时发送和接受的数据碰撞问题。
2. 序列化与反序列化格式
在实践中,序列化包含的内容不止有数据化结构的信息,还应包含有数据信息的总体长度,以及用于区分各给内容的分隔符:
"len"\r\n"{json}"\r\n
“len”:是"{json}"的总长度,在网络通信中,传输过来的报文可能并不完整,如果“len”和实际长度不符,那么该报文应该舍弃而不解析。
\r\n:是用作为分隔符的符号,在网络通信中,相同报文可能会堆积。那么就需要分隔符来区分哪一部分是“len”那一部分是整体报文。
“{json}”:是序列化的数据化结构,jsoncpp库提供了对其进行解析的接口。
3. jsoncpp
jsoncpp是一个开源的第三方c++库,它可以用于生产.json文件,也提供了将数据序列化与反序列化的接口。在Linux系统中,使用该库需要先安装:
ubuntu: sudo apt-get install libjsoncpp-dev
centos: sudo yum install jsoncpp-devel
3.1 序列化与反序列化常用API
#include <jsoncpp/json/json.h>
3.2 Json::Value
Json::Value
Json::Value
是一个类类型,其定义的对象一般取名为root,因为这是一个树状结构,且使用的是映射关系存储序列化数据。
Json::Value
使用operator[]
来存储key
和value
。其中key必须是字符串,而value则支持cpp的大部分原生类型及json形式的类型。示例:root["x"]=_x;
3.3 Json::FastWriter
Json::FastWriter
Json::String Json::FastWriter::write(const Json::Value &root)
Json::FastWriter
是一个类类型,其定义的对象一般取名为writer,,write()
是其成员函数,它将Json::Value
对象存储的数据序列化为字符串,字符串的形式为"{json}"
。
3.4 Json::Reader
Json::Reader
bool Json::Reader::parse(std::istream& is, Value& root, bool collectComments = true)
Json::Value::Int Json::Value::asInt() const
Json::Reader
是一个类类型,其定义的对象一般取名为reader,它用于将序列化的数据反序列化。parse()
是其成员函数,它将传递进来的json序列化字符串is
,传输到Value
对象root
中,随后指明root
中value的类型即可实现反序列化。
asInt()
是Value
类中的一个成员函数,其在反序列化中,将特定的key对应的value指明类型提取出来,如该函数为将value按照int类型提取,示例:_x=root["x"].asInt();
。类似的函数还有asCstring()
、asString()
、asBool()
、asDouble()
等。