前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux Socket 收发Json

Linux Socket 收发Json

作者头像
用户5908113
发布2020-06-28 16:27:31
4.7K0
发布2020-06-28 16:27:31
举报
文章被收录于专栏:Pou光明

点击上方蓝字可直接关注!方便下次阅读。如果对你有帮助,麻烦点个在看或点个赞,感谢~

不管是Qt开发还是linux 嵌入式应用开发,一个人的核心竞争力还是不断思考,也就是不断琢磨。

下面的程序主要是Linux C Socket 读取JSON文件并传输,然后再写入文件,其中使用了cJSON库,关于cJSON库不过多介绍,主要介绍整体的思路。

1. Server 端

使用的是socket 阻塞式,没有使用select、poll、epoll等

接收端按照JSON格式解析数据,并提取感兴趣Key所对应的Value

程序功能挺快就可以做好,做完之后进行拆解,将socket通信独立出来,JSON解析、写文件、响应客户端JSON数据等分别写成函数。

对函数入参的判断、文件操作等的成功与否的判断;程序实际功能代码并不是很多,但是参数检查、结果判断等也占了一些空间

Main函数调用:

代码语言:javascript
复制
#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;
}

函数封装:

代码语言:javascript
复制
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);

一些具体实现:

代码语言:javascript
复制
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;
        }
        else
        {
            nRet = -1;
            goto end;
        }

    }
    else
    {
        nRet = -1;
        goto end;
    }

    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;
        }   
    }
    else
    {
        nRet = -1;
    }

    if (rootWriteFile)
    {
        cJSON_Delete(rootWriteFile);
        rootWriteFile = NULL;
    }  

    return nRet;
}

注意一下JSON的空间释放

2. 客户端

客户端主要是读取一个JSON文件,然后发送

之后接收服务器响应的JSON数据:在原有数据基础上添加成功与否的标志

具体测试程序:

代码语言:javascript
复制
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;
        }
      }

    }

    close(sockfd);

    puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
    return EXIT_SUCCESS;
}

3. 程序效果

4. 小结

编译JSON时需要链接linux的数学库

自己琢磨如何拆解函数功能

应用程序也主要是调用别人的api,那么你的核心竞争力是什么呢 ?

如需程序工程可在公众号后台留言。

请保持对经济的敏感性,如白酒基金、医药基金等连续几个月的上涨,自己是否无动于衷?当然需要有自己的投资方式与风格。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Pou光明 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档