在Neptune上搭建并部署http服务器
本文首发于51cto【查看原文链接】
转载:本人
注:本文只进行功能介绍与代码实现,具体原理见设计文档(点此跳转)
效果演示
实现了语音操控开、关灯
实现方法简介
我们知道浏览器是http的客户端,目的是连接远程的http服务器,然后服务器返回浏览器数据.浏览器接收数据解析数据之后展现出来.我们看到的外在表现就是,浏览器访问一个url,然后就得到相应的web页面.
所以我们需要在Neptune上部署一个http服务器。
为了实现tcp通信,这里使用socket库搭建,代码如下:
文件见附件(可直接编译,由于某些原因智能在ohos1.1版本下运行,后续会更新ohos3.x版本)
代码实现
tcp_service_demo1
#include #include #include #include "net_demo_common.h"#include "net_common.h"#include "cmsis_os2.h"#include "ohos_init.h"#include "wifiiot_gpio.h"#include "wifiiot_gpio_ex.h"#include "wifiiot_gpio_w800.h"#define LED_TASK_STACK_SIZE 1024#define LED_TASK_PRIO 25static void my_demo(){ printf("\n\n\nhello!\n\n\n\n"); GpioInit(); GpioSetDir(WIFI_IOT_GPIO_PB_08, WIFI_IOT_GPIO_DIR_OUTPUT);// output is 0 PB08 control led GpioSetDir(WIFI_IOT_GPIO_PB_09, WIFI_IOT_GPIO_DIR_INPUT);// input is PB09 IoSetPull(WIFI_IOT_GPIO_PB_09, WIFI_IOT_GPIO_ATTR_PULLHIGH); GpioRegisterIsrFunc(WIFI_IOT_GPIO_PB_09, WIFI_IOT_INT_TYPE_EDGE, WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, NULL, NULL); GpioSetOutputVal(WIFI_IOT_GPIO_PB_08, WIFI_IOT_GPIO_VALUE0); printf("\n\ndone\n\n\n\n");}static char request[128] = "";void TcpServerTest(unsigned short port){ printf("*TCP server test *\n"); int retval = 0; int backlog = 1; int sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP socket int connfd = -1; struct sockaddr_in clientAddr = {0}; socklen_t clientAddrLen = sizeof(clientAddr); struct sockaddr_in serverAddr = {0}; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(port); // 端口号,从主机字节序转为网络字节序 serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); // 允许任意主机接入, 0.0.0.0 retval = bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)); // 绑定端口 if (retval < 0) { printf("bind failed, %ld!\r\n", retval); goto do_cleanup; } printf("bind to port %d success!\r\n", port); retval = listen(sockfd, backlog); // 开始监听 if (retval < 0) { printf("listen failed!\r\n"); goto do_cleanup; } printf("listen with %d backlog success!\r\n", backlog); // 接受客户端连接,成功会返回一个表示连接的 socket , clientAddr 参数将会携带客户端主机和端口信息 ;失败返回 -1 // 此后的 收、发 都在 表示连接的 socket 上进行;之后 sockfd 依然可以继续接受其他客户端的连接, // UNIX系统上经典的并发模型是“每个连接一个进程”——创建子进程处理连接,父进程继续接受其他客户端的连接 // 鸿蒙liteos-a内核之上,可以使用UNIX的“每个连接一个进程”的并发模型 // liteos-m内核之上,可以使用“每个连接一个线程”的并发模型 connfd = accept(sockfd, (struct sockaddr *)&clientAddr, &clientAddrLen); if (connfd < 0) { printf("accept failed, %d, %d\r\n", connfd, errno); goto do_cleanup; } printf("accept success, connfd = %d!\r\n", connfd); printf("client addr info: host = %s, port = %d\r\n", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port)); my_demo(); //send http pages const char buffer[9162]="HTTP/1.1 200 OK\r\nDate: Fri, 22 May 2009 06:07:21 GMT\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n<body style="text-align:center;font-size: larger;">Hello Openharmony!
<div style="background-color:green ;height: 20%;color:white;">开灯
要让开发板连接网络,需要在 net_params.h里修改配网参数
#ifndef NET_PARAMS_H#define NET_PARAMS_H#define PARAM_HOTSPOT_SSID "FsrLab" // your AP SSID#define PARAM_HOTSPOT_PSK "12345678" // your AP PSK#define PARAM_HOTSPOT_TYPE WIFI_SEC_TYPE_PSK // defined in wifi_device_config.h#define PARAM_SERVER_ADDR "192.168.0.113" // your PC IP address#define PARAM_SERVER_PORT 5678//设置端口号#endif // NET_PARAMS_H
修改my_demo/Build.gn
static_library("demo") { sources = ["tcp_service_test.c" ] include_dirs = [ "//utils/native/lite/include", "//kernel/liteos_m/components/cmsis/2.0", "//foundation/communication/interfaces/kits/wifi_lite/wifiservice", "//base/iot_hardware/interfaces/kits/wifiiot_lite", ] if (board_name == "w800" || board_name == "hi3861v100") { sources += ["wifi_connecter.c", "net_demo_ohos.c"] } if (board_name == "w800") { include_dirs += [ "//vendor/winnermicro/w800/src/network/lwip2.0.3/include/", "//vendor/winnermicro/w800/include/arch/xt804/csi_core", "//vendor/winnermicro/w800/include/arch/xt804", "//vendor/winnermicro/w800/include/platform", "//vendor/winnermicro/w800/include/os", "//vendor/winnermicro/w800/include/net", "//vendor/winnermicro/w800/include/app", "//vendor/winnermicro/w800/include/wifi", "//vendor/winnermicro/w800/include", ] }}
修改build.gn:
import("//build/lite/config/component/lite_component.gni")lite_component("app") { features = [ "my_demo:demo", ]}