首发于 编程456

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;