作者:王石
在《[二] 第一个OpenHarmony程序》我们熟悉了如何在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客户端-鸿蒙开发者社区 #冲刺创作新星# [十二]简单Http客户端-鸿蒙开发者社区](https://dl-harmonyos.51cto.com/images/202210/761f290456a7816647750358c03a7a22557878.png?x-oss-process=image/resize,w_466,h_165)
在浏览器输入www.baidu.com然后回车即可看到浏览器显示了百度的页面,按F12可以看到具体内容:
![#冲刺创作新星# [十二]简单Http客户端-鸿蒙开发者社区 #冲刺创作新星# [十二]简单Http客户端-鸿蒙开发者社区](https://dl-harmonyos.51cto.com/images/202210/65884d94498efc11918753f56c7698890c6c4a.png?x-oss-process=image/resize,w_601,h_777)
上图里我们可以看到在请求的url是www.baidu.com,请求的方法是GET,服务器的IP地址是180.101.49.14:443(https,若是http就是80)
此样例参考小熊派设计,使用小熊派HM_Micro开发板进行验证
应用开发流程
-
建立Build.gn
-
建立helloworld.c
-
添加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;
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
-
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");
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;
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
-
在main里增加方法和头文件
-
测试结果
-
Get测试结果
![#冲刺创作新星# [十二]简单Http客户端-鸿蒙开发者社区 #冲刺创作新星# [十二]简单Http客户端-鸿蒙开发者社区](https://dl-harmonyos.51cto.com/images/202210/2682d8c98dd33485eee246ffb06e58875c7729.png?x-oss-process=image/resize,w_719,h_841)
-
Post测试结果
![#冲刺创作新星# [十二]简单Http客户端-鸿蒙开发者社区 #冲刺创作新星# [十二]简单Http客户端-鸿蒙开发者社区](https://dl-harmonyos.51cto.com/images/202210/b356b29925cf9f773e2178fe6a9597cb1b6463.png?x-oss-process=image/resize,w_820,h_624)
总结
- http是建立在socket之上的数据结构化应用协议,可以通过拼socket包实现所有功能;
- 之后我们可以利用此接口实现一个核算地图的界面应用;
参考链接:
https://gitee.com/bearpi/bearpi-hm_micro_app/blob/master/README.md
了解下鸿蒙开发HTTP请求消息的方式
重温下HTTP
http通常还是TCP运行的多