本篇文章主要是对微信小程序连接小熊派的通信过程进行记录与整合。下面将以点亮开发板的灯为案例来讲,如果浏览量可以的话,我会尝试出正式开发环境下微信小程序与华为开发板通信的案例,请点赞或评论。
开发环境
【开发板】:BearPi-HM_Nano 【芯片手册】:Hi3861V100 【微信小程序版本】:稳定版 Stable Build (1.05.2201240 | 1.06.2201240)
开发板UDP接口
在socket.h 中包含声明UDP协议相关接口函数。
接口名 | 功能描述 |
---|
socket | 创建套接字 | bind | 将ip和端口绑定到嵌套字 | sendto | 将数据由指定的socket发送给对方主机 | recvfrom | 从指定主机接收UDP数据 | close | 关闭套接字 |
开启和连接UDP服务器的条件:
- 需要连接WiFi
- 客户端与服务器需要在同一局域网
UDP服务器创建流程
下面将会按照顺序讲解UDP服务器整体创建过程
- 连接WiFi
通过连接WiFi可以知道UDP服务器的IP地址,后续微信小程序通过这个IP地址发送消息。WifiConnect(WIFI_ACCOUNT, WIFI_PASSWD);
- 创建Socket
网络通信需要创建socket,这样两个端才能通过套接字发送和接收数据。
int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
- 设置UDP服务器和UDP客户端
通过设置INADDR_ANY 参数接收任何主机发送过来的数据,并且指定服务器使用哪个端口。
struct sockaddr_in server_sock;
server_sock.sin_family = AF_INET;
server_sock.sin_addr.s_addr = htonl(INADDR_ANY);
server_sock.sin_port = htons(8888);
struct sockaddr_in client_sock;
- Socket与UDP服务器进行绑定
bind(sock_fd, (struct sockaddr *)&server_sock, sizeof(struct sockaddr)
上面的步骤完成后,可以通过sendto() 与recvfrom() 发送和接收数据。
开启UDP服务器完整代码(不含LED部分)
#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "lwip/sockets.h"
#include "wifi_connect.h"
#define WIFI_ACCOUNT "请填写WiFi的SSID"
#define WIFI_PASSWD "请填写WiFi的密码"
#define _PROT_ "请填写服务器的端口号"
int sock_fd, new_sock_fd;
char recvBuff[512];
char *buff = "I'm UDP Server.\r\n";
static void UDPServerTask(void)
{
printf("Into UDPServerTask!\r\n");
struct sockaddr_in server_sock;
server_sock.sin_family = AF_INET;
server_sock.sin_addr.s_addr = htonl(INADDR_ANY);
server_sock.sin_port = htons(_PROT_);
struct sockaddr_in client_sock;
socklen_t sin_size;
printf("Into WiFi!\r\n");
WifiConnect(WIFI_ACCOUNT, WIFI_PASSWD);
printf("Create Socket\r\n");
if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("Socket Is Error.\r\n");
exit(1);
}
printf("Clean Data.\r\n");
bzero(&server_sock, sizeof(server_sock));
printf("Bind Socket and Adrr.\r\n");
if (bind(sock_fd, (struct sockaddr *)&server_sock, sizeof(struct sockaddr)) == -1)
{
perror("Bind Is Error.\r\n");
exit(1);
}
ssize_t ret;
while (1)
{
sin_size = sizeof(struct sockaddr_in);
while (1)
{
printf("Clean Data.\r\n");
bzero(recvBuff, sizeof(recvBuff));
if ((ret = recvfrom(sock_fd, recvBuff, sizeof(recvBuff), 0, (struct sockaddr *)&client_sock, (socklen_t *)&sin_size)) == -1)
{
printf("Recv Error.\r\n");
}
if ((ret = sendto(new_sock_fd, buff, strlen(buff) + 1, 0, (struct sockaddr *)&client_sock, sizeof(client_sock))) == -1)
{
printf("Send : \r\n");
}
}
printf("Close Server.\r\n");
close(new_sock_fd);
}
}
static void UDPServerEntry(void)
{
osThreadAttr_t threadAttr;
threadAttr.attr_bits = 0U;
threadAttr.cb_mem = NULL;
threadAttr.cb_size = 0U;
threadAttr.stack_mem = NULL;
threadAttr.stack_size = 10240;
threadAttr.priority = 24;
threadAttr.name = "UDPServerTask";
if (osThreadNew((osThreadFunc_t)UDPServerTask, NULL, &threadAttr) == NULL){
printf("Falied To Create UDPServerTask.\r\n");
}
}
APP_FEATURE_INIT(UDPServerEntry);
相关函数说明
void perror(const char *);
int bzero((void *)(target), (size_t)(size));
int exit(1);
int close(int);
微信UDP客户端创建流程
创建UDP客户端基本流程:
- 创建UDP客户端
this.udp = wx.createUDPSocket();
- 绑定端口号
可以不指定port ,将会随机绑定一个本机可用端口号this.udp.bind(number port);
- 设置接收函数
callback 为处理接收到消息的函数this.udp.onMessage(function callback);
- 向UDP服务器发送消息
this.udp.send(Object object);
UDP客户端完整代码(不含LED部分)
<view class="container">
<button bindtap="send">向UDP服务发送消息</button>
</view>
<view class="res_container">
{{udpResData}}
</view>
const app = getApp()
let Utf8ArrayToStr = require('./Utf8ArrayToStr.js');
Page({
data: {
udpResData: ''
},
send: function(e) {
this.udp.send({
address: '172.17.3.8',
port: '3641',
message: 'hello, how are you'
})
},
onUdpMessage: function(res) {
console.log(res);
if(res.remoteInfo.size > 0) {
console.log('onUdpMessage() 接收数据 ' + res.remoteInfo.size + ' 字节:' + JSON.stringify(res, null, '\t'));
let messageStr = Utf8ArrayToStr.Utf8ArrayToStr(new Uint8Array(res.message))
this.setData({
udpResData: 'udp接收到的内容: ' + messageStr
})
}
},
onLoad: function () {
this.udp = wx.createUDPSocket()
this.udp.bind()
this.udp.onMessage(this.onUdpMessage)
console.log('页面 index 加载完成事件onLoad()')
},
})
function Utf8ArrayToStr(array) {
var out, i, len, c;
var char2, char3;
out = "";
len = array.length;
i = 0;
while (i < len) {
c = array[i++];
switch (c >> 4) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
out += String.fromCharCode(c);
break;
case 12: case 13:
char2 = array[i++];
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
char2 = array[i++];
char3 = array[i++];
out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
}
}
return out;
}
module.exports = {
Utf8ArrayToStr: Utf8ArrayToStr
}
如果你是无意刷到这篇文章并看到这里,希望你给我的文章来一个赞赞👍👍。如果你不同意其中的内容或有什么问题都可以在下方评论区留下你的想法或疑惑,谢谢你的支持!!😀😀
参考资料
- HarmonyOS WiFi编程开发–UDP服务端
- 微信小程序局域网通信之UDP通信demo
- UDPSocket | 微信开发文档
|