C语言使用json-c发送网络数据
程序员文章站
2022-07-14 19:01:18
...
之前做项目的时候,在嵌入式端侧用到了json数据格式,主要负责和服务器通信使用。json-c网上的资料很少,所以下面总结一些,再附上一些代码,供大家参考使用。
json-c安装:
apt-get install libjson0-dev
libjson0-dev软件包里面有json-c的头文件以及开发需要的库文件。头文件放在了/usr/include/json/json.h目录下,写代码的时候要注意!或者安装下面这个包也行:
apt-get install libjson-c-dev
json-c类型
typedef enum json_type {
/* If you change this, be sure to update json_type_to_name() too */
json_type_null,
json_type_boolean,
json_type_double,
json_type_int,
json_type_object,
json_type_array,
json_type_string,
} json_type;
来自头文件,写代码的时候有时候需要判断json类型,根据json类型来解析。
json-c部分接口
1、将符合json格式的字符串构造为一个json对象
struct json_object *json_tokener_parse(const char *s);
2、将json对象内容,转成json格式的字符串
const char *json_object_to_json_string(struct json_object *obj);
3、创建json对象
struct json_object *json_object_new_object();
4、往json对象中添加键值对
void json_object_object_add(struct json_object *obj, const char *key, struct json_object *value);
5、将C字符串转换为JSON字符串格式的对象
struct json_object* json_object_new_string(const char *s);
6、将整数转换为JSON格式的对象
struct json_object* json_object_new_int(int32_t i);
7、获取json对象的整形数值(和5相反的操作)
int32_t json_object_get_int(struct json_object *obj);
8、获取json对象的字符串值(和6相反的操作)
const char *json_object_get_string(struct json_object *obj);
解析json分为两步:
第一步:根据键名,从json对象中获取对应数据的json对象
第二步:根据数据类型,将数据对应的json对象转化为对应类型的数据
9、根据键名获取对应的json对象
json_bool json_object_object_get_ex(struct json_object* obj, const char *key, struct json_object **value);
参数:obj 源json对象 key 键名 value 用于存放获取的对应数据的json对象,注意这里一定传入的是二级指针。不用传入实体
10、获取json对象的类型 类型有
json_type json_object_get_type(struct json_object *obj);
数组类型相关操作(json_type_array类型)
11、创建一个JSON数组类型JSON对象
struct json_object* json_object_new_array(void);
12、往json_type_array类型的json对象中添加一个元素
int json_object_array_add(struct json_object *obj, struct json_object *val);
13、获取json_type_array类型的json对象中指定下标的元素
struct json_object* json_object_array_get_idx(struct json_object *obj, int idx);
json对象和json格式字符串的转换
#include <stdio.h>
#include <json-c/json.h>
#include <string.h>
int main()
{
const char *str = "{\"name\":\"jack\",\"age\":22,\"sex\":\"male\"}";
//把符合json格式的字符串转换成json对象
struct json_object *obj = json_tokener_parse(str);
//把json对象转换成字符串输出
printf("%s\n", json_object_to_json_string(obj));
return 0;
}
json封装和解析
#include <stdio.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_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对象
struct json_object *json;
json_object_object_get_ex(obj, "name", &json);
//第二步 根据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对象转换成字符串类型
}
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;
}
socket传输json数据(TCP)
服务器
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <json-c/json.h>
int main()
{
//创建socket
int sockfd = socket(AF_INET, SOCK_STREAM, 0); //ipv4协议 流式套接字 具体的协议类型
if (-1 == sockfd)
{
perror("socket");
exit(1);
}
int opt = 1;
setsockopt(sockfd,SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); //地址可以被重复绑定
struct sockaddr_in server_addr; //保存服务器的信息
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = 8000;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //127.0.0.1回环ip 表示本机 测试时候可以用
//绑定信息
int ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (-1 == ret)
{
perror("bind");
exit(1);
}
//设置监听队列
ret = listen(sockfd, 10);
if (-1 == ret)
{
perror("listen");
exit(1);
}
printf("等待客户端的连接...\n");
struct sockaddr_in client_addr; //用于保存客户端的信息
int length = sizeof(client_addr);
//接受连接(建立TCP连接)
int fd = accept(sockfd, (struct sockaddr *)&client_addr, &length);
if (-1 == fd)
{
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(sockfd);
return 0;
}
客户端
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <json-c/json.h>
int main()
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == sockfd)
{
perror("socket");
exit(1);
}
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = 8000;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
//向服务器发起连接
int ret = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (-1 == ret)
{
perror("connect");
exit(1);
}
struct json_object *json = json_object_new_object();
json_object_object_add(json, "name", json_object_new_string("jack"));
json_object_object_add(json, "age", json_object_new_int(11));
json_object_object_add(json, "sex", json_object_new_string("male"));
const char *buf = json_object_to_json_string(json);
ret = send(sockfd, buf, strlen(buf), 0);
if (-1 == ret)
{
perror("send");
exit(1);
}
printf("字符串 %s 发送成功 长度 %ld!\n", buf, strlen(buf));
close(sockfd);
return 0;
}
更多精彩视频、文章、嵌入式学习资料,微信关注公众号 【学益得智能硬件】