前言:
为什么需要json打包:
为了避免不同平台下字节对齐、类型大小不统一 的问题,json库把数据封装成具有一定格式的字符流数据,进行传输。
json格式:
把数据与键值一一对应,数据传输双方约定好同一键值,使用接口API根据键值操jason对象(jason_object)存储或取得数据。
一般使用:
数据--->(封装)json对象--->string格式---------> ---->传输---->---->String格式---->(解析)jason对象---->取得数据(int、char..)数据,与键值成对存入json对象——>通过键值从json对象取得数据
json接口API:(注意:在json中所有数据类型(arry、int、string、char)都是一个jason对象)
1、数据的封装(单对象(int、char、string)和数组(arry))
(1)新建对象:
A.创建一个Json对象:
struct json_object * json_object_new_object (void)
B.创建一个Json数组对象:
struct json_object * json_object_new_array (void)
C.销毁json对象
void json_object_put (struct json_object *obj)
(2)json对象的转换(普通类型->json对象):
1:struct json_object * json_object_new_int (int i)
2:struct json_object * json_object_new_double (double d)
3:struct json_object * json_object_new_string (const char *s)
4:struct json_object * json_object_new_boolean (boolean b)
5:struct json_object * json_object_new_string_len (const char *s, int len)
(3)json对象的处理:
A.普通对象
添加:void json_object_object_add (struct json_object *obj, const char *key, struct json_object *val)
删除:void json_object_object_del (struct json_object *obj, const char *key)
查询:struct json_object * json_object_object_get (struct json_object *obj, const char *key)
根据key获取:struct json_object * json_object_object_get (struct json_object *obj, const char *key)
B.数组对象
获取长度:int json_object_array_length (struct json_object *obj)
添加:int json_object_array_add (struct json_object *obj, struct json_object *val)
指定位置添加:int json_object_array_put_idx (struct json_object *obj, int idx, struct json_object *val)
获取指定位置对象:struct json_object * json_object_array_get_idx (struct json_object *obj, int idx)
(4)json_object To 字符流:
const char * json_object_to_json_string (struct json_object *obj)
2、数据解析:解包
(1)字符流 To json_object
struct json_object* json_tokener_parse(const char *str)
(2)对象获取
A.普通对象
根据key获取:struct json_object * json_object_object_get (struct json_object *obj, const char *key)
B.数组对象
获取指定位置对象:struct json_object * json_object_array_get_idx (struct json_object *obj, int idx)
(3)对象的转换(数据还原)
bool型:boolean json_object_get_boolean (struct json_object *obj)
double型:double json_object_get_double (struct json_object *obj)
整型:int json_object_get_int (struct json_object *obj)
字符数组:const char * json_object_get_string (struct json_object *obj)
3、测试
(1)先定义需要打包的结构体,可以自己定义,这里采用结构体方便多种类型的数据传输。个人可根据自己需求打包数据。
//通信结构体
typedef struct user
{
int work; //工作指令
int flag; //反馈信息
char username[30]; //登录昵称
char passwd[30]; //登录密码
char othername[30]; //私聊对象
char msg[300]; //消息内容
int online; //在线状态
}data_t;
(2)打包函数:
//打包数据-
const char * pack_user(data_t user){
//创建大对象
struct json_object* objects= json_object_new_object();
//2>将数据打包成json小对象(约定的结构体中有几个成员就打包几个小对象)
struct json_object* values1=json_object_new_int(user.work);
struct json_object* values2=json_object_new_int(user.flag);
struct json_object* values3=json_object_new_string(user.username);
struct json_object* values4=json_object_new_string(user.passwd);
struct json_object* values5=json_object_new_string(user.othername);
struct json_object* values6=json_object_new_string(user.msg);
struct json_object* values7=json_object_new_int(user.online);
//3>贴标签放入大对象
json_object_object_add (objects,"work",values1);
json_object_object_add (objects,"flag",values2);
json_object_object_add (objects,"username",values3);
json_object_object_add (objects,"passwd",values4);
json_object_object_add (objects,"othername",values5);
json_object_object_add (objects,"msg",values6);
json_object_object_add (objects,"online",values7);
//4>大对象转成字符串类型
const char *p=json_object_to_json_string(objects);
// printf("test 263\n");
char* str = malloc(500); // 动态分配内存
strcpy(str,p);
return str;
}
(3)解包数据函数:
data_t unpack_user( const char *js){
static data_t rslt;
//解析json,还原数据成原来的类型
struct json_object * sale_json=json_tokener_parse(js);
//根据标签key获取小对象数据
struct json_object * sale_obj1=json_object_object_get(sale_json,"work");
struct json_object * sale_obj2=json_object_object_get(sale_json,"flag");
struct json_object * sale_obj3=json_object_object_get(sale_json,"username");
struct json_object * sale_obj4=json_object_object_get(sale_json,"passwd");
struct json_object * sale_obj5=json_object_object_get(sale_json,"othername");
struct json_object * sale_obj6=json_object_object_get(sale_json,"msg");
struct json_object * sale_obj7=json_object_object_get(sale_json,"online");
//提取小对象里面的数据
rslt.work=json_object_get_int (sale_obj1);
rslt.flag=json_object_get_int (sale_obj2);
strcpy(rslt.username,json_object_get_string (sale_obj3));
//strcpy(rslt.username,wd1);
strcpy(rslt.passwd,json_object_get_string (sale_obj4));
//strcpy(rslt.passwd,wd2);
strcpy(rslt.othername,json_object_get_string (sale_obj5));
//strcpy(rslt.othername,wd3);
strcpy(rslt.msg,json_object_get_string (sale_obj6));
//strcpy(rslt.msg,wd4);
rslt.online=json_object_get_int (sale_obj7);
return rslt;
}
(4)使用:
char buf[100];
//接受打包传来的数据,放在buf里面
bzero(buf,strlen(buf));//清空buf里面的垃圾值,再接受
int ret = recv(cid,buf,sizeof(char)*1000,0);//接收数据
//将打包的数据赋值给data_t类型
data_t request = unpack_user(buf);
//将结构体打包成char*类型,通过strcpy函数赋值给p
char *p;
strcpy(p,pack_user(request)));