Linux Socket 收发Json
不管是Qt开发还是linux 嵌入式应用开发,一个人的核心竞争力还是不断思考,也就是不断琢磨。
下面的程序主要是Linux C Socket 读取JSON文件并传输,然后再写入文件,其中使用了cJSON库,关于cJSON库不过多介绍,主要介绍整体的思路。
Server 端
使用的是socket 阻塞式,没有使用select、poll、epoll等
接收端按照JSON格式解析数据,并提取感兴趣Key所对应的Value
程序功能挺快就可以做好,做完之后进行拆解,将socket通信独立出来,JSON解析、写文件、响应客户端JSON数据等分别写成函数。
对函数入参的判断、文件操作等的成功与否的判断;程序实际功能代码并不是很多,但是参数检查、结果判断等也占了一些空间
Main函数调用:
#include "socketServer.h"
#include <stdio.h>
int main()
int socketServerFd = -1;
socketServerFd = SocketServer_Init("127.0.0.1", 9999);
if(-1 == socketServerFd)
printf("create socket server fd faild \n");
RecDataFromClient(socketServerFd);
return 0;
函数封装:
int ParseRecvJsonData(const char * recvdata, int *outLogLevel);
int WriteLogLevelToFileJson(const char *filePathName, int logLevel);
int CreateRespondInfoJson(char *respondInfoJson, const char* recvJsonData,const int writeFileRet);
int SocketServer_Init(const char *ip, int port);
int RecDataFromClient(int serverFd);
一些具体实现:
int ParseRecvJsonData(const char * recvdata, int *outLogLevel)
int nRet = -1;
*outLogLevel = -1;
if(NULL == recvdata)
return -1;
cJSON *parseRoot = NULL;
cJSON *levelItem = NULL;
parseRoot = cJSON_Parse(recvdata);
if (parseRoot)
levelItem = cJSON_GetObjectItem(parseRoot, "level");
if (levelItem)
*outLogLevel = levelItem->valueint;
nRet = 0;
nRet = -1;
goto end;
nRet = -1;
goto end;
if (parseRoot)
cJSON_Delete(parseRoot);
parseRoot = NULL;
return nRet;
int WriteLogLevelToFileJson(const char *filePathName, int logLevel)
int nRet = 0;
cJSON * rootWriteFile = NULL;
if((NULL == filePathName) || (logLevel < 1) ||
(logLevel > 8))
return -1;
rootWriteFile = cJSON_CreateObject();
if (rootWriteFile)
cJSON_AddNumberToObject(rootWriteFile,"level",logLevel);
char *fileStream = cJSON_Print(rootWriteFile); //convert json to buf
FILE *fid;
fid = fopen(filePathName,"w");
if (!fid)
printf("open file faild \n");
nRet = -1;
nRet = fwrite(fileStream, sizeof(char), strlen(fileStream), fid);
if (!nRet)
printf("写出文件出错\n");
nRet = -1;
nRet = fclose(fid);
if (nRet)
printf("close fileFd faild \n");
nRet = -1;
nRet = -1;
if (rootWriteFile)
cJSON_Delete(rootWriteFile);
rootWriteFile = NULL;
return nRet;
注意一下JSON的空间释放
2.客户端
客户端主要是读取一个JSON文件,然后发送
之后接收服务器响应的JSON数据:在原有数据基础上添加成功与否的标志
具体测试程序:
int main(void)
FILE *fid;
fid = fopen("/home/dh/workSpace/Learn/cJSON/testCJSON/clientSendData/bin/test.json","r");
if(fid == NULL)
printf("读取文件出错");
return -1;
//获取文件大小
fseek (fid , 0 , SEEK_END);
int lSize = ftell(fid);
rewind (fid);
//开辟存储空间
int num = lSize/sizeof(char);
char *jsonData = (char*) malloc (sizeof(char)*num);
if (jsonData == NULL)
printf("开辟空间出错\n");
return -1;
fread(jsonData,sizeof(char),num,fid);
// if(NULL != jsonData)
// free(jsonData); //释放内存
fclose(fid);
// 定义socket
int sockfd = socket(AF_INET,SOCK_STREAM,0);
// 定义sockaddr_in
struct sockaddr_in skaddr;
skaddr.sin_family = AF_INET;
skaddr.sin_port = htons(PORT);
skaddr.sin_addr.s_addr = inet_addr(SERV);
if( connect(sockfd,(struct sockaddr *)&skaddr, sizeof(skaddr)) < 0 )
printf("connect error \n");
exit(1);
printf("connect server success !!! \n");
char sendbuf[BUFF] = {0};
char recvbuf[BUFF] = {0};
// while( fgets(sendbuf, sizeof(sendbuf), stdin) != NULL )
// send(sockfd, sendbuf, strlen(sendbuf), 0);
// if( strcmp(sendbuf,"exit\n") == 0)
// {
// break;
// }
while( 1 )
int sendSize = send(sockfd, jsonData, strlen(jsonData), 0);
printf("send size %d \n", sendSize);
//usleep(1000);
int recvSize = recv(sockfd, recvbuf, sizeof(recvbuf), 0);
while (-1 == recvSize)
recvSize = recv(sockfd, recvbuf, sizeof(recvbuf), 0);
if(recvSize > 0)
printf("recv data size %d \n", recvSize);
cJSON *parseRoot = NULL;
parseRoot = cJSON_Parse(recvbuf);
char *out = cJSON_Print(parseRoot); //将json形式打印成正常字符串形式
printf("%s \n",out);
if(parseRoot)
cJSON_Delete(parseRoot);
parseRoot = NULL;