首页 > 其他分享 >#冲刺创作新星# #跟着小白一起学鸿蒙# [十二]简单Http客户端

#冲刺创作新星# #跟着小白一起学鸿蒙# [十二]简单Http客户端

时间:2022-11-07 16:31:30浏览次数:60  
标签:HTTP 鸿蒙 printf Http include BUF servaddr SIZE 客户端

作者:王石

在《#跟着小白一起学鸿蒙# [二] 第一个OpenHarmony程序》我们熟悉了如何在开源鸿蒙开发应用,并通过hdc工具拷贝至开发板运行。但是那时候我们只是打印了最简单的hello world,接下来我们就讲开发最常用的部分,一个简单的http客户端;

概述

  • HTTP 是一个基于 TCP/IP 通信协议来传递数据(HTML 文件、图片文件、查询结果等);
  • HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出;
  • HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息;

HTTP请求消息Request

  • 请求数据结构如下

requeststruct.png

  • 一个Get的sample

在浏览器输入www.baidu.com然后回车即可看到浏览器显示了百度的页面,按F12可以看到具体内容:

httpget.png

上图里我们可以看到在请求的url是www.baidu.com,请求的方法是GET,服务器的IP地址是180.101.49.14:443(https,若是http就是80)

  • 一个Post的sample httppost.png

    上图里我们可以看到在请求的url是https://cysz.hopethink.com/qhhsd/app/getH5HsdList,请求的方法是POST,服务器的IP地址是114.215.124.251:443(https,若是http就是80),请求内容类型application/x-www-form-urlencoded;charset=UTF-8,请求数据长度84,请求数据keyword=&streetId=&pageNum=1&pageSize=1&ip=222.95.30.84

此样例参考小熊派设计,使用小熊派HM_Micro开发板进行验证

应用开发流程

graph LR
建立build.gn --> 建立helloworld.c --> 添加httpget --> 添加httppost --> 验证
  1. 建立Build.gn

    import("//build/lite/config/component/lite_component.gni")
    
    executable("hello_world_lib") {
        output_name = "hello_world"
        sources = [ "hello_world.c" ]
        include_dirs = []
        defines = []
        cflags_c = []
        ldflags = []
    }
    
    lite_component("my_app") {
        features = [
            ":hello_world_lib",
        ]
    }
    
  2. 建立helloworld.c

    #include <stdio.h>
    int main(int argc, char **argv)
    {
        printf("\n************************************************\n");
        printf("\n\t\tHello httpget!\n");
        printf("\n************************************************\n\n");
        
        return 0;
    }
    
  3. 添加httpget

    int sockfd, ret, i, h;
    struct sockaddr_in servaddr;
    char str1[BUF_SIZE], str2[BUF_SIZE], buf[BUF_SIZE], *str;
    socklen_t len;
    fd_set   t_set1;
    struct timeval  tv;
            
    //创建套接字
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
        printf("create socket failed--- exit(0)!\n");
        exit(0);
    };
    
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    if (inet_pton(AF_INET, IPSTR_GET, &servaddr.sin_addr) <= 0 ){
        printf("inet_pton failed --- exit(0)!\n");
        exit(0);
    };
    
    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){
        printf("connect failed, exit(0)!\n");
        exit(0);
    }
    printf("connect remote server\n");
    memset(str2, 0, BUF_SIZE);
    strcat(str2, "theDataToGet");
    str=(char *)malloc(BUF_SIZE);
    len = strlen(str2);
    sprintf(str, "%d", len);
    //请求头部内容
    memset(str1, 0, BUF_SIZE);
    strcat(str1, "GET / HTTP/1.1\n");
    strcat(str1, "Host: www.baidu.com\n");
    strcat(str1, "Content-Type: text/html\n");
    strcat(str1, "Content-Length: ");
    strcat(str1, str);
    //请求空行
    strcat(str1, "\n\n");
    //请求参数
    strcat(str1, str2);
    strcat(str1, "\r\n\r\n");
    printf("%s\n",str1);
    
    ret = write(sockfd,str1,strlen(str1));
    if (ret < 0) {
        printf("socket write failed! errcode%d,errmsg'%s'\n",errno, strerror(errno));
        exit(0);
    }else{
        printf("socket write %d bytes!\n\n", ret);
    }
    
    FD_ZERO(&t_set1);
    FD_SET(sockfd, &t_set1);
    
    while(1) {
        sleep(2);
        h = 0;
        h = select(sockfd +1, &t_set1, NULL, NULL, &tv);
        if (h < 0) {
            close(sockfd);
            printf("SELECT error, return -1!\n");
            return -1;
        };
    
        if (h > 0){
            memset(buf, 0, BUF_SIZE);
            i= read(sockfd, buf, BUF_SIZE);
            if (i==0){
                close(sockfd);
                printf("read 0, return -1!\n");
                return -1;
            }
    
            printf("%s\n", buf);
        }
    }
    close(sockfd);
    return 0;
    
  4. httppost

    int sockfd, ret, i, h;
    struct sockaddr_in servaddr;
    char str1[BUF_SIZE], str2[BUF_SIZE], buf[BUF_SIZE], *str;
    socklen_t len;
    fd_set   t_set1;
    struct timeval  tv;
    
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
        printf("create sockt failed---exit(0)!\n");
        exit(0);
    };
    
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    if (inet_pton(AF_INET, IPSTR_POST, &servaddr.sin_addr) <= 0 ){
        printf("inet_pton failed---exit(0)!\n");
        exit(0);
    };
    
    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){
        printf("connect server failed, exit(0)!\n");
        exit(0);
    }
    printf("connect to server\n");
    
    memset(str2, 0, BUF_SIZE);
    strcat(str2, "keyword=&streetId=&pageNum=1&pageSize=1&ip=222.95.30.84");
    str=(char *)malloc(BUF_SIZE);
    len = strlen(str2);
    sprintf(str, "%d", len);
    //请求头部内容
    memset(str1, 0, BUF_SIZE);
    strcat(str1, "POST /qhhsd/app/getH5HsdList HTTP/1.1\n");
    strcat(str1, "Host: cysz.hopethink.com\n");
    strcat(str1, "Content-Type: application/x-www-form-urlencoded\n");
    strcat(str1, "Content-Length: ");
    strcat(str1, str);
    //请求空行
    strcat(str1, "\n\n");
    //str2的值为post的数据
    strcat(str1, str2);
    strcat(str1, "\r\n\r\n");
    printf("%s\n",str1);
    
    ret = write(sockfd,str1,strlen(str1));
    if (ret < 0) {
        printf("socket write failed! errcode%d, errmsg'%s'\n",errno, strerror(errno));
        exit(0);
    }else{
    	printf("socket write %d bytes\n\n", ret);
    }
    
    FD_ZERO(&t_set1);
    FD_SET(sockfd, &t_set1);
    
    tv.tv_sec= 0;
    tv.tv_usec= 0;
    h= 0;
    
    while(1) {
        sleep(2);
        h = select(sockfd +1, &t_set1, NULL, NULL, &tv);
        if (h == -1) {
            close(sockfd);
            printf("select error, return -1\n");
            return -1;
    	};
        if ( FD_ISSET(sockfd, &t_set1) ){
            memset(buf, 0, BUF_SIZE);
            i= read(sockfd, buf, BUF_SIZE);
            if (i==0){
                close(sockfd);
                printf("read 0, return -1!\n");
                return -1;
            }
        	printf("%s\n", buf);
    	}
    }
    close(sockfd);
    return 0;
    
  5. 在main里增加方法和头文件

    • 头文件

      
      #include <stdio.h>
      #include <sys/socket.h>
      #include <sys/types.h>
      #include <time.h>
      #include <errno.h>
      #include <signal.h>
      #include <stdlib.h>
      #include <string.h>
      #include <unistd.h>
      #include <sys/wait.h>
      #include <sys/time.h>
      #include <netinet/in.h>
      #include <arpa/inet.h>
       
      #define IPSTR_GET "180.101.49.14" //服务器IP地址,上面查出来的;
      #define IPSTR_POST "114.215.124.251"
      
      #define PORT 80
      #define BUF_SIZE 4096
      
    • 方法

      httpget();
      httppost();
      
  6. 测试结果

    1. Get测试结果 getresult.png

    2. Post测试结果 postresult.png

总结

  1. http是建立在socket之上的数据结构化应用协议,可以通过拼socket包实现所有功能;
  2. 之后我们可以利用此接口实现一个核算地图的界面应用;

参考链接:

https://gitee.com/bearpi/bearpi-hm_micro_app/blob/master/README.md

本文作者:左翼风发

想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com/#bkwz​

标签:HTTP,鸿蒙,printf,Http,include,BUF,servaddr,SIZE,客户端
From: https://blog.51cto.com/harmonyos/5828510

相关文章

  • HTTP的请求与响应
    http请求浏览器中输入url后,浏览器向网站所在服务器发送了一个请求,网站服务器接收请求,并对这个请求进行处理和解析,然后返回对应的响应,传回给浏览器,再通过浏览器解析出来请......
  • nginx1.18配置https,tomcat9也配置https
    生成证书:https://www.cnblogs.com/caidingyu/p/11904277.htmltomcat9https://blog.csdn.net/lzj_lives/article/details/123824964server.xml<Connectorport="90......
  • git推送错误:error: failed to push some refs to 'https://github.com/xxxxxxxxxx.git
    git推送到github仓库时,报错,如图报错原因:出现错误的主要原因是github中的README.md文件不在本地代码目录中 解决方案:1、输入以下命令,将远程库中的更新合并到(pull=fetc......
  • 解决Playwright访问https证书问题
    #参数说明ignore_https_errors=True访问https地址解决安全证书viewport={"width":1920,"height":1080}最大化打开浏览器,参数可设置。eg:page=browser.new_pa......
  • 国内HTTP代理具有哪些类型
    HTTP代理类型一共能分为四种。除了前面提到的透明代理,匿名代理,高匿代理,还有混淆代理。从安全程度来说,这四种代理类型的排序是高匿>混淆>匿名>透明。代理类型主要取决于......
  • HTTP代理在网站运营中发挥巨大作用
    代理服务器能够让我们的网络使用更加的快速便捷,这是由代理技术所带来的改变,我们需要好好了解。像是在网站运营中,很多资源是不可少的,它能够将产品营销所应用的网络资源......
  • 通过哪些途径可以获取http代理
    我们平时在很多地方都需要用到HTTP代理,例如效果补单、数据爬虫等等,如果没有http代理的支撑我们的工作很难继续开展下去,那么通过哪些途径可以获取HTTP代理呢?一、收......
  • HTTP代理对个人隐私的保护
    随着时代的进步,网络的发达,依靠网络工作的人员也越来越多,HTTP代理的存在帮助了很多网络工作人员达到了高效率的工作。HTTP代理不仅网络工作人员可以常用到,个人也可以使......
  • HTTP的发展历史
    互联网的始祖-阿帕网在1968年6月3日,罗伯茨向泰勒描述了建立阿帕网的计划,18天后,也就是6月21日,泰勒批准了这个计划,14个月后阿帕网建立。在1973年ARPA网扩展成......
  • Nginx configure error: the HTTP rewrite module requires the PCRE library
    IssueWhen configure nginx1.19.0,runthecommands../configure--prefix=/opt/nginx-1.19.0CopyButthefollowingerror occurs.checkingforPCRElibr......