目录
json_object_get_string 和 json_object_to_json_string有何区别:
为什么使用json
JSON (JavaScript Object Notation, JS 对象简谱)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。
- 1.数据格式比较简单, 易于读写, 格式都是压缩的, 占用带宽小
- 2.易于解析这种语言, 客户端JavaScript可以简单的通过eval()进行JSON数据的读取
- 3.因为JSON格式能够直接为服务器端代码使用, 大大简化了服务器端和客户端的代码开发量, 但是完成的任务不变, 且易于维护。
说明:
比如说在客户端与服务器之间完成一个注册过程,由客户端向服务器传输一个注册信息的结构体,在实际登陆的过程中我们可能只需要用到id和passwd这两个信息,其余的部分并不需要这一部分就浪费掉了,后续如果还有聊天功能,包括另外的信息我们只能通过在该结构体中加入更多的信息,这会导致传输的结构体过大。
JSON用起来比结构体更加灵活,JSON不同于结构体,是不固定的。JSON 数据格式与语言无关,脱胎自JavaScript,但当前很多编程语言都支持 JSON 格式数据的生成和解析。
JSON 的官方 MIME 类型是 application/json,文件扩展名是 .json
什么是json
json简介
JSON (JavaScript Object Notation ,JS 对象简谱)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。
json-c
json-c库中是嵌入式开发中常用的库,因为很多地方都以json数据交互协议,尤其嵌入式web数据交互时通常会用到json格式,因此如果需要在产品端进行json数据解析,json-c是一个不错的选择。
json-c 的安装
如果出现:
E: 无法定位软件包 libjson0-dev
E: 无法定位软件包 libjson0
第一种情况:
在确定网络连接和质量没问题的情况下,任何软件都无法安装,出现E:无法定位XXX
解决:换源
具体步骤:
1、备份 /etc/apt/sources.list 文件
执行命令:
sudo cp /etc/apt/sources.list /etc/apt/sources.list.old
2、打开文件 sudo vim /etc/apt/sources.list
(gedit也可以 建议gedit可以直接复制)
将原文件里面的内容删掉或注释掉
粘贴选择的源:直接粘贴替换
阿里云源:
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
清华源:
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ trusty main universe restricted multiverse deb http://archive.ubuntu.com/ubuntu/ trusty main universe restricted multiverse
3、更新apt源
apt update
查看可以更新的软件
apt list --upgradable
更新软件
apt upgrade
第二种情况
sudo apr-get update
json-c API
#include<stdio.h>
#include<stdlib.h>
#include<json-c/json.h>
int main(){
const char *str="{\"name\":\"jack\",\"age\":22,\"sex\":\"male\"}";
//把符合json格式的字符串转换成json对象
struct json_object *obj = json_tokener_parse(str);
//把json对象转化成字符串对象输出 返回对象char*
printf("%s\n",json_object_to_json_string(obj));
return 0;
}
编译:
编译的时候需要加上后缀,因为我们json-c是外来库
gcc json.c -o json -ljson-c
输出结果:
json对象
struct json_object *obj
字符串转换成json对象
json_tokener_parse(str)
json对象转化成字符串
json_object_to_json_string(obj)
json_object_get_string 和 json_object_to_json_string
有何区别:
const char * json_object_to_json_string (struct json_object *obj)
将json_object转化为json格式的string,这个方法与后面的json_object_get_string不同,大家知道json对象的结构为:key:test value :haha ;
那么to_json_string对象后,结构为:='latitude':116.40091896057129,'longitude':39.931129903495886
而json_object_get_string仅仅负责对单纯"test"的json对象转化,例如:
json_object * j_o = json_object_new_string("test");
char * pointer_char = json_object_get_string(j_o); //结果pointer_char 为"test"
自己组合一个json
往json对象添加键值对
json_object_object_add
#include<stdio.h>
#include<stdlib.h>
#include<json-c/json.h>
int main(){
//创建空json对象
struct json_object *obj = json_object_new_object();
//往json对象添加键值对 json_object_object_add
//json_object_new_string把字符串转换成json对象
json_object_object_add(obj, "name", json_object_new_string("jack"));
//json_object_new_int把数字转换成json对象
json_object_object_add(obj, "age", json_object_new_int(11));
json_object_object_add(obj, "sex", json_object_new_string("male"));
//打印json对象
printf("%s\n",json_object_to_json_string(obj));
return 0;
}
解析json
第一步,根据键名,从json对象中获取对应数据的json对象
第二部,根据数据类型,将数据对应的json对象转化为对应类型的数据
#include<stdio.h>
#include<stdlib.h>
#include<json-c/json.h>
int main(){
//创建空json对象
struct json_object *obj = json_object_new_object();
//往json对象添加键值对
//json_object_new_string把字符串转换成json对象
json_object_object_add(obj, "name", json_object_new_string("jack"));
//json_object_new_int把数字转换成json对象
json_object_object_add(obj, "age", json_object_new_int(11));
json_object_object_add(obj, "sex", json_object_new_string("male"));
//打印json对象
printf("%s\n",json_object_to_json_string(obj));
//
//解析json
//json_object_object_get_ex(对象, 键 ,解析出来的对象);
//第一步,根据键名,从json对象中获取对应键的json对象
struct json_object *json;
json_object_object_get_ex(obj, "name", &json);
//第二部,根据数据类型,将数据对应的json对象转化为对应类型的数据
//先获取对象类型
json_type type = json_object_get_type(json);
if(json_type_string == type){
printf("name : %s\n", json_object_get_string(json));
}
json_object_object_get_ex(obj, "age", &json);
printf("age : %d\n", json_object_get_int(json));
json_object_object_get_ex(obj, "sex", &json);
printf("sex : %s\n", json_object_get_string(json));
return 0;
}
从json对象中获取对应键的json对象
json_object_object_get_ex(obj, "name", &json);
//json_object_object_get_ex(对象, 键 ,解析出来的对象地址);
获取对象类型
json_type type = json_object_get_type(json);
解析结果
创建json数组对象并解析出来
#include<stdio.h>
#include<stdlib.h>
#include<json-c/json.h>
int main(){
//创建json空对象
struct json_object *obj = json_object_new_object();
json_object_object_add(obj, "name", json_object_new_string("jack"));
//创建json数组对象
struct json_object *array = json_object_new_array();
//json_object_array_add添加array元素
json_object_array_add(array, json_object_new_int(100));
json_object_array_add(array, json_object_new_int(90));
json_object_array_add(array, json_object_new_int(80));
//把数组对象添加到json对象中
json_object_object_add(obj, "score",array);
//打印出来
printf("%s\n",json_object_to_json_string(obj));
//解析json数组对象
struct json_object *json;
json_object_object_get_ex(obj, "score", &json);//从obj中解析"score"键对应的值放到json中
if(json_object_get_type(json) == json_type_array) //判断类型
{
int i;
int size = json_object_array_length(json); //获取json_type_array类型json对象长度
for(i = 0; i<size; i++)//遍历打印
{
struct json_object *j = json_object_array_get_idx(json,i); //根据下标提取json对象
if(json_type_int == json_object_get_type(j)){
printf("%d\n",json_object_get_int(j));
}
}
}
return 0;
}
JSON数据传输实战演练
实现客户端服务器端之间传输接收:
{"name":"jack","age":11,"sex":"male" }
客户端:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<json-c/json.h>
int main()
{
//创建一个socket
int clientfd = socket(AF_INET, SOCK_STREAM, 0);
if(clientfd == -1)
{
perror("socket");
exit(-1);
}
//连接服务器
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
serveraddr.sin_port = 8000;
//向服务器发起连接
if(connect(clientfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) == -1){
perror("connect");
exit(-1);
}
//创建json对象
struct json_object *obj = json_object_new_object();
json_object_object_add(obj, "name", json_object_new_string("jack"));
json_object_object_add(obj, "age", json_object_new_int(11));
json_object_object_add(obj, "sex", json_object_new_string("male"));
//json对象转化成字符串
const char* buf = json_object_to_json_string(obj);
//向服务器发送消息
int ret = send(clientfd, buf, strlen(buf),0);
if(-1==ret)
{
perror("send");
exit(-1);
}
printf("字符串 %s 发送成功 长度 %ld!\n", buf, strlen(buf));
close(clientfd);
return 0;
}
服务器端:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<json-c/json.h>
int main()
{
//创建一个监听socket
int listenfd = socket(AF_INET, SOCK_STREAM, 0); //ipv4协议 流式套接字 具体的协议类型
if(listenfd==-1){
perror("socket");
exit(-1);
}
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); //地址可以被重复绑定
//初始化服务器地址
struct sockaddr_in bindaddr;
bindaddr.sin_family = AF_INET;
bindaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
bindaddr.sin_port = 8000;
//绑定信息
if(bind(listenfd, (struct sockaddr*) &bindaddr, sizeof(bindaddr))){
perror("listen");
return -1;
}
//启动监听
int ret = listen(listenfd,10);
if(ret == -1){
perror("listen");
exit(-1);
}
printf("等待客户端的连接....\n");
struct sockaddr_in clientaddr; //用于保存客户端的信息
socklen_t clientaddrlen = sizeof(clientaddr);
//接收客户端连接
int fd = accept(listenfd, (struct sockaddr *)&clientaddr, &clientaddrlen);
if(fd == -1){
perror("accept");
exit(1);
}
printf("接受客户端的连接 %d\n",fd);
char *buf = (char *)malloc(sizeof(char) *1024);
//从fd接受消息,TCP连接相当于一个文件,fd就是文件描述符,从fd读取数据,就是从TCP连接接收数据
ret = recv(fd, buf, 1024, 0);
if(-1 == ret)
{
perror("recv");
exit(1);
}
//字符串转换成json
struct json_object *obj = json_tokener_parse(buf);
struct json_object *json; //存放
json_object_object_get_ex(obj, "name", &json);
printf("name : %s\n", json_object_get_string(json));
json_object_object_get_ex(obj, "age", &json);
printf("age : %d\n", json_object_get_int(json));
json_object_object_get_ex(obj, "sex", &json);
printf("sex : %s\n", json_object_get_string(json));
close(fd);
close(listenfd);
}