跟着小白一起学鸿蒙--]简单Http客户端(十二)

系统 OpenHarmony
HTTP 是一个基于 TCP/IP 通信协议来传递数据(HTML 文件、图片文件、查询结果等)。

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

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

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

在《#跟着小白一起学鸿蒙# [二] 第一个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

  • 请求数据结构如下

#冲刺创作新星# #跟着小白一起学鸿蒙# [十二]简单Http客户端-开源基础软件社区

  • 一个Get的sample

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

#冲刺创作新星# #跟着小白一起学鸿蒙# [十二]简单Http客户端-开源基础软件社区

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

  • 一个Post的sample

#冲刺创作新星# #跟着小白一起学鸿蒙# [十二]简单Http客户端-开源基础软件社区

  • 上图里我们可以看到在请求的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 --> 验证

建立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",
]
}

建立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;
}

添加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;

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;

在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();

测试结果:

Get测试结果:

Post测试结果:

总结

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

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

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

​https://ost.51cto.com​​。

责任编辑:jianghua 来源: 51CTO开源基础软件社区
相关推荐

2022-11-29 16:35:02

Tetris鸿蒙

2022-12-02 14:20:09

Tetris鸿蒙

2023-04-04 09:24:11

鸿蒙HiDumper

2022-10-10 14:47:04

蓝牙应用鸿蒙

2023-03-30 09:32:27

2022-11-14 17:01:34

游戏开发画布功能

2022-10-17 14:29:24

鸿蒙应用开发

2023-02-27 16:30:32

鸿蒙开源协议分析

2022-08-19 19:02:20

开源鸿蒙操作系统

2023-03-30 09:19:54

SELinux安全子系统

2023-01-03 15:09:10

鸿蒙常用工具

2023-03-15 16:19:03

BinderIPC工具

2022-12-06 15:39:16

鸿蒙主干代码

2022-11-24 14:34:41

Hap程序鸿蒙

2022-10-20 16:40:16

JS应用控制LED鸿蒙

2022-10-09 15:05:50

NAPI框架鸿蒙

2023-04-06 09:18:52

鸿蒙AVPlayerAVRecorder

2022-12-05 15:02:14

鸿蒙用户鉴权

2022-12-09 15:34:38

2022-11-28 15:42:39

分布式软总线鸿蒙
点赞
收藏

51CTO技术栈公众号