首页 > 其他分享 >http与cJSON练习

http与cJSON练习

时间:2024-06-11 21:56:38浏览次数:26  
标签:http addr cJSON errno 练习 weather include recv

http与cJSON练习

/****************************************************************************************************
*                                       weather_test.c
*               练习tcp连接,与http协议,调用服务器接口,实现获取特定城市的天气信息,并用cJSON解析
*               需要添加cJSON.c和cJSON.h
*               下载地址https://github.com/DaveGamble/cJSON
****************************************************************************************************/
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdbool.h>
#include <netdb.h>

#include "cJSON.h"

#define PORT 80                                //http协议默认80端口
#define DOMAIN_NAME "api.seniverse.com"            //天气接口API,此处使用的是心知天气
#define CITY        "Jieyang"                      //城市
#define KEY      "S23Bdt3KcyGvyz3kb"            //密钥

//套接字
int tcp_socket = 0;

//接收缓冲区
char recv_buf[1024] = {0};

/**
 *函数名称	connect_init
 *函数功能	初始化tcp连接
 *函数参数	NONE
 *返回结果	布尔型
 *注意事项	NONE
 */
bool connect_init()
{  
    //创建TCP套接字
	tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (tcp_socket == -1)
	{
		fprintf(stderr, "tcp socket error,errno:%d,%s\n",
                errno,strerror(errno)
                );
		return false;
	}

    /*****************************相关结构体*******************************/
        //  struct hostent {
        //        char  *h_name;            /* official name of host */
        //        char **h_aliases;         /* alias list */
        //        int    h_addrtype;        /* host address type */
        //        int    h_length;          /* length of address */
        //        char **h_addr_list;       /* list of addresses */
        //    }
    /********************************************************************/
    //解析域名
    struct hostent* ipaddr=gethostbyname(DOMAIN_NAME);

    struct in_addr *addr = (struct in_addr *)ipaddr->h_addr_list[0];
    printf("%s\n", inet_ntoa(*addr));

    //初始化结构体
    struct sockaddr_in weather_addr;
    //协议
    weather_addr.sin_family         = AF_INET;
    //端口
    weather_addr.sin_port          = htons(PORT);
    //服务器地址
    weather_addr.sin_addr. s_addr   = inet_addr(    inet_ntoa(*addr)    );

    //开始连接
    int ret = connect(tcp_socket,(struct sockaddr*)&weather_addr,sizeof(weather_addr));
    if(-1 == ret){
        fprintf(stderr, "connect error,errno:%d,%s\n",
                errno,strerror(errno)
                );
		return false;
    }
    printf("连接成功\n");
    return true;
}



/**
 *函数名称	request_http
 *函数功能	http请求
 *函数参数	NONE
 *返回结果	NONE
 *注意事项	NONE
 */
void request_http()
{
    //请求缓冲区
    char req_buf[1024] = {0};
    //向缓冲区写入请求
    sprintf(req_buf,"GET https://api.seniverse.com/v3/weather/now.json?key=%s&location=%s&language=zh-Hans&unit=c "  //空格不能省略
            "HTTP/1.1"
            "\r\n"
            "HOST:%s\r\n"
            "\r\n"
            ,KEY,CITY,DOMAIN_NAME
            );

    //循环请求直到成功接收信息
    while(1){

        //发送请求
        if( -1 == send(tcp_socket,req_buf,sizeof(req_buf),0) ){
            fprintf(stderr,"send error,errno[%d]:%s\n",
                    errno,strerror(errno)
                    );
            continue;
        }
        printf("请求发送成功\n");

        //第一次接收响应
        if( -1 == recv(tcp_socket,recv_buf,sizeof(recv_buf),0)  ){

            fprintf(stderr,"recv error,errno[%d]:%s\n",
                    errno,strerror(errno)
                    );
            continue;
        }

        printf("%s\n",recv_buf);
        //清零
        bzero(recv_buf,1024);
        printf("*******************************************\n");
        //第二次接收响应
        if(-1 == recv(tcp_socket,recv_buf,sizeof(recv_buf),0)){

            fprintf(stderr,"recv error,errno[%d]:%s\n",
                    errno,strerror(errno)
                    );
            continue;
        }
        //此处不可清零,需要解析JSON
        printf("%s\n",recv_buf);
        break;
    }
    
}

/**
 *函数名称	weather_JSON
 *函数功能	解析JSON
 *函数参数	NONE
 *返回结果	NONE
 *注意事项	NONE
 */
void weather_JSON()
{
    //将字符串转换为josn格式
    cJSON* weather = cJSON_Parse(recv_buf);
    //解析
    cJSON* results  = cJSON_GetObjectItem(weather, "results");
    cJSON* array    = cJSON_GetArrayItem(results,0);

    cJSON* location = cJSON_GetObjectItem(array,"location");

    cJSON* name     = cJSON_GetObjectItem(location,"name");
    cJSON* country  = cJSON_GetObjectItem(location,"country");

    cJSON* now      = cJSON_GetObjectItem(array,"now");
    cJSON* text     = cJSON_GetObjectItem(now,"text");

    cJSON* last_update = cJSON_GetObjectItem(array,"last_update");

    /*****************************相关结构体*******************************/
        // typedef struct cJSON {
        //     struct cJSON *next,*prev;	
        //     struct cJSON *child;		

        //     int type;					

        //     char *valuestring;			
        //     int valueint;				
        //     double valuedouble;			

        //     char *string;				
        // } cJSON;
    /********************************************************************/
    printf("当前城市%s-%s,该城市天气为%s   %s\n",   country->valuestring,
                                                    name->valuestring,
                                                    text->valuestring,
                                                    last_update->valuestring
                                                    );

}


int main()
{
    connect_init();
    request_http();
    weather_JSON();
    return 0;
}

运行结果
image

标签:http,addr,cJSON,errno,练习,weather,include,recv
From: https://www.cnblogs.com/waibibabu-/p/18242822

相关文章

  • 利用聚合API平台的API接口,利用HTTP协议向服务器发送请求,并接受服务器的响应,要求利用cJ
    目录题目分析代码结果题目利用聚合API平台的API接口,利用HTTP协议向服务器发送请求,并接受服务器的响应,要求利用cJSON库对服务器的响应数据进行解析,并输出到终端分析1.需从源代码网站GitHub或SourceForge代码网站下载cJSON库及阅读下载的README相关手册如何使用cJSON库;2.使用......
  • 网络编程练习题---利用cJSON库对服务器返回的JSON格式数据完成解析
    目录题目注意事项实现代码结果展示相关接口指引题目利用某些平台(聚合API、百度AI、科大讯飞API)的API接口,利用HTTP协议向服务器发送请求,并接受服务器的响应,要求利用cJSON库对服务器的响应数据进行解析,并输出到终端。注意事项1.预测的日期开始时间为2010-01-012."老黄历"API......
  • 网络编程练习题
    网络编程代码#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<stdio.h>#include<errno.h>#include<sys/socket.h>#include<netinet/in.h>#include<netinet/ip.h>#include<arpa......
  • cJSON学习及简单应用小结
    JSON简介JSON(JavaScriptObjectNotation,JavaScript对象表示法)是一种轻量级的数据交换格式。它基于ECMAScript(欧洲计算机制造商协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得JSON成为理想的数据交换语言。以下是JSON......
  • 基于centos7.9搭建http文件服务器
    基于centos7.9搭建http文件服务器1.安装httpd[root@localhost~]#yuminstall-yhttpd2.关闭防火墙以及selinux[root@localhost~]#systemctlstopfirewalld&&setenforce03.修改相关配置​ 文件/etc/httpd/conf/httpd.conf中的默认参数(自定义修改)[root@loca......
  • 高级循环练习
    无限循环无限循环是循环一直停不下来语法:for(;;){System.out.println("开心");}while(true){System.out.println("开心");}do{System.out.println("开心");}while(true);先排除do…while因为一般不常用for和while学过应该用哪个呢?首先for记住是有......
  • CTFHUB技能树之WEB前置技能HTTP协议
    CTFHUB技能树WEB前置技能/HTTP协议请求方式根据提示可知,通过修改请求方式获取flag使用BurpSuite进行拦截,将GET方法改为CTFHUB方法即可。得到flag。302跳转打开BurpSuite进行拦截,将第一次请求发给重发器再次发送,得出flagCookie打开页面,得出提示信息,需要admin,将Cook......
  • C#、.Net通过HttpWebRequest请求WebService接口
    点击查看代码///<summary>///测试按钮中调用WebService接口///</summary>///<paramname="sender"></param>///<paramname="e"></param>privatevoidbutton1_Click(objectsender,EventArgse){//strin......
  • .net8 aspire 启动不用https 报ASPIRE_ALLOW_UNSECURED_TRANSPORT故障
    故障显示System.AggregateException:“Oneormoreerrorsoccurred.(The'applicationUrl'settingmustbeanhttpsaddressunlessthe'ASPIRE_ALLOW_UNSECURED_TRANSPORT'environmentvariableissettotrue.Thisconfigurationiscommonlyset......
  • SRE 排障利器,接口请求超时试试 httpstat
    夜莺资深用户群有人推荐的一个工具,看了一下真挺好的,也推荐给大家。需求场景A服务调用B服务的HTTP接口,发现B服务返回超时,不确定是网络的问题还是B服务的问题,需要排查。工具简介就类似curl,httpstat也可以请求某个后端,而且可以把各个阶段的耗时都展示出来,包括DNS解......