编写一个基于命令行的获取物流快递信息的程序。(云市场快递API、HTTP、JSON)

更多资料请点击:我的目录
本篇仅用于记录自己所学知识及应用,代码仍可优化,仅供参考,如果发现有错误的地方,尽管留言于我,谢谢。

运行结果:
在这里插入图片描述

main.c部分:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include "cJSON.h"

char *httpRequest()
{
    
    
    static char request[1024];
    printf("请求获取信息!\n\n");
    snprintf(request, 1024, "GET /kdi?no=780098068058&type=zto HTTP/1.1\r\n"
                            "Host:wuliu.market.alicloudapi.com\r\n"
                            "Authorization:APPCODE 8b75a704109c42069f4990211121212\r\n"
                            "\r\n");
    return request;
}

int main()
{
    
    
    struct hostent *he = gethostbyname("wuliu.market.alicloudapi.com");
    if(he == NULL)
    {
    
    
        perror("DNS解析失败");
        exit(0);
    }
    printf("IP:%s\n", inet_ntoa(*((struct in_addr *)(he->h_addr_list)[0])));
    char buf[20] = {
    
    0};
    sprintf(buf,"%s",inet_ntoa(*((struct in_addr *)(he->h_addr_list)[0])));

    struct sockaddr_in bindaddr;                                                    //定义ipv4地址结构体变量
    bzero(&bindaddr,sizeof(bindaddr));
    bindaddr.sin_family=AF_INET;
    bindaddr.sin_addr.s_addr=inet_addr("192.168.1.157");                            //绑定客户端自己的ip地址
    bindaddr.sin_port=htons(10000);                                                 //绑定客户端自己的端口号

    struct sockaddr_in serveraddr;                                                  //定义结构体变量存放对方(服务器)的ip和端口号
    bzero(&serveraddr,sizeof(serveraddr));
    serveraddr.sin_family=AF_INET;
    serveraddr.sin_addr.s_addr=inet_addr(buf);                                      //服务器的ip地址
    serveraddr.sin_port=htons(80);                                                  //服务器的端口号

    int tcpsock=socket(AF_INET,SOCK_STREAM,0);                                      //创建tcp套接字
    if(tcpsock==-1)
    {
    
    
        perror("创建tcp套接字!\n");
        return -1;
    }

    int on=1;
    setsockopt(tcpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));                     //设置端口释放后立即就可以被再次使用

    int ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));            //绑定ip和端口号
    if(ret==-1)
    {
    
    
        perror("绑定失败!\n");
        return -1;
    }

    ret=connect(tcpsock,(struct sockaddr *)&serveraddr,sizeof(serveraddr));         //连接服务器
    if(ret==-1)
    {
    
    
        perror("连接服务器失败!\n");
        return -1;
    }
    else
    {
    
    
        printf("链接成功!\n");
    }

    char *s = httpRequest();
    write(tcpsock, s, strlen(s));

    // 接收服务器的 HTTP 响应
    char *response = calloc(100, 1024);
    int total = 0;
    while(1)
    {
    
    
        if(total > 100*1024)
        {
    
    
            printf("响应数据超过100k,请重新分配内存\n");
            break;
        }

        int n = read(tcpsock, response+total, 10*1024);
        if(n <= 0)
            break;

        total += n;
    }

    //printf("响应报文:%s", response);

    char *sbuf = calloc(100, 1024);
    strtok(response,"{");                                                           //以第一个大括号分割
    sprintf(sbuf,"{%s}}",strtok(NULL,"\0"));                                        //补回被分割的{
    
    
    //printf("JSON数据:%s", sbuf);                 
    
    //通过https://www.bejson.com/jsonviewernew/查看JSON视图
    cJSON* root = cJSON_Parse(sbuf);              									//从给定的json字符串中得到cjson对象,(root即为根目录)   
    cJSON* result = cJSON_GetObjectItem(root, "result"); 							//根据键获取对应的值(cjson对象),(root_body即为root的下一级目录)
    cJSON* list = cJSON_GetObjectItem(result, "list");        						//根据键获取对应的值(cjson对象)
    
	for(int i = 0; i < cJSON_GetArraySize(list); i ++)
	{
    
    
		cJSON* point = cJSON_GetArrayItem(list,i);
		printf("%s\n",cJSON_GetArrayItem(point,0)->valuestring);
		printf("%s\n",cJSON_GetArrayItem(point,1)->valuestring);
	}
    
    cJSON_Delete(root);                                                           //将json结构占用的数据空间释放
    
    return 0;
}

cJSON部分:

链接:https://pan.baidu.com/s/1zLebKOF7NHqF7f8Spl7G_Q 
提取码:2u0j 

解压后将文件放在main.c同目录下:

终端编译指令:  gcc main.c cJSON.c -L cJSON.h
终端运行指令: ./a.out 

request的信息 与 cJSON的用法

猜你喜欢

转载自blog.csdn.net/weixin_43793181/article/details/108522822
今日推荐