前期知识:网络七层协议(OSI)基础知识

文章代码参考

微信小程序UDP通信

微信小程序UDP通信及编码转换

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
import Encoder  from '../../util/Encoder.js'
onLoad() {
this.udp = wx.createUDPSocket() //新建udp实例
this.udp.bind(60000) //udp绑定本机
},
methods: {
//连接目标
linkUDP() {
this.udp.connect({
address: '192.168.0.87',
port: 50000,
})
},
//发送信息
clickUDP() {
//utf-8转gbk编码
var gbkArray = Encoder.hexstrToArray(Encoder.stringToGbkHexstr('123哈'));
console.log("gbkArray>>" , gbkArray)
let gbk = new ArrayBuffer()
console.log(gbk)

this.udp.write({
address: '192.168.0.87',
port: 50000,
message: gbk
})
},
//监听接收到的数据
onUdpMessage: function(res) {
console.log('收到的信息', res);
console.log('onUdpMessage() 接收数据 ' + res.remoteInfo.size + ' 字节:' + JSON.stringify(res, null, '\t'));
// gbk转utf-8
var x = new Uint8Array(res.message);
var str = new TextDecoder('gbk').decode(x);
console.log(str)
},
},
mounted() {
//监听收到的数据
this.udp.onMessage(this.onUdpMessage)
//监听错误的信息
this.udp.onError(function(err) {
console.log(err)
})
}

关于微信小程序使用UDP实现局域网通讯及UDP模块的封装

封装模块

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
export class UDPSocket {
constructor() {
this.connection = {};
}
// 创建一个UDP实例
establish(monitor) {
console.log(monitor);
this.connection = wx.createUDPSocket();
// 绑定指定端口
const port = this.connection.bind(monitor)
console.log('连接成功' + port + '端口');
}
// 监听端口函数
onListening(success, failure, open, cmd, mac) {
// 开启监听
this.connection.onListening((res) => {
open(res)
console.log(res);
})
// 监听回调函数
this.connection.onMessage((res) => {
console.log(res);

//以下为我对数据的处理,使用到了我的一个tool.js,里面包含了对字节数组的处理
//需要的可以到我的个人博客获取www.meinaodai.top

// 做空包筛查
if (res.message) {
var packet = tool.analysis(res.message)
// 做数据空包处理
if (packet) {
// 做数据筛查
// console.log(tool.Screening(packet, cmd, mac));
success(tool.Screening(packet, cmd, mac))
console.log(packet);
console.log('------------------------');
}
}
})
// debug
this.connection.onError((err) => {
failure(err)
})
}
// 发送消息
send(message) {
this.connection.send({
address: '255.255.255.255',
port: 20015,
message
})
}
// 关闭搜索事件
UDPclose() {
this.connection.close()
console.log('UDP关闭');
}
}

模块引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var UDP = require("./UDP.js")   
// UDP实例创建
this.UDPSocket = new UDP.UDPSocket();
// 连接端口
this.UDPSocket.establish(20016)
// 请求设备上报状态
this.udpsend()
// 开始监听
this.UDPSocket.onListening(res => {
if (res) {
console.log(res);
}
}, err => {
// debug
console.log(err);
}, open => {
console.log(open);
},
//这两个参数为筛查条件,用于过滤无用或者不合法的信息,不需要的可传空值
'', getApp().globalData.item.mac)

实际工程测试

先按照第一篇写时发现找不到 connect 函数,是因为变量问题!修改为全局变量后可以通过 connect 连接端口,但又缺失 hexstrToArray 函数,就没再继续下去。
后来找到第二篇参考,并根据参考写相应UDP函数,引用中 getApp().globalData.item.mac 和 tool.analysis(res.message) 均不存在,屏蔽即可,数据能正常收发。
再重新分析参考程序,并从官方文档中了解相应函数作用,最后基本按照官方文档提供的几个函数即可完成功能。

在页面初始中建立实例并绑定端口

也可以使用 connect 模式,使用 bind 可以返回绑定端口
使用 onListening 打开监听功能,并通过 onMessage 设置监听数据回调函数

1
2
3
4
5
6
7
8
9
10
11
12
13
onLoad(options) {
this.udp = wx.createUDPSocket() //新建udp实例

const port = this.udp.bind(60000)
console.log('端口' + port + '连接成功');

this.udp.onListening(res=>{
console.log(res)
})
this.udp.onMessage(res=>{
console.log(res)
})
},

设置数据发送

发送数据直接使用 send 函数即可,使用 255.255.255.255 是广播模式
即向局域网中所有端口 60000 均发送数据

1
2
3
4
5
6
7
8
9
BtnTest(){
console.log("这是一个测试按钮");

this.udp.send({
address: '255.255.255.255',
port: 60000,
message: 'hello, how are you'
})
},

待添加部分

以上只是简单的数据收发,也在局域网中测试实现,不过完整的过程封装应该还需错误回调和关闭等功能。
即增加 UDPSocket.onError 和 UDPSocket.close 函数
官方所提供的函数如下:
UDPSocket wx.createUDPSocket() 创建一个 UDP Socket 实例

UDPSocket 基础库 2.7.0 开始支持,低版本需做兼容处理。
一个 UDP Socket 实例,默认使用 IPv4 协议

方法:

函数名 说明
number UDPSocket.bind(number port) 绑定一个系统随机分配的可用端口,或绑定一个指定的端口号
UDPSocket.setTTL(number ttl) 设置 IP_TTL 套接字选项,用于设置一个 IP 数据包传输时允许的最大跳步数
UDPSocket.send(Object object) 向指定的 IP 和 port 发送消息。基础库 2.9.0 起支持广播 (指定地址为 255.255.255.255)
UDPSocket.connect(Object object) 预先连接到指定的 IP 和 port,需要配合 write 方法一起使用
UDPSocket.write() 用法与 send 方法相同,如果没有预先调用 connect 则与 send 无差异(注意即使调用了 connect 也需要在本接口填入地址和端口参数)
UDPSocket.close() 关闭 UDP Socket 实例,相当于销毁。 在关闭之后,UDP Socket 实例不能再发送消息,每次调用 UDPSocket.send 将会触发错误事件,并且 message 事件回调函数也不会再也执行。在 UDPSocket 实例被创建后将被 Native 强引用,保证其不被 GC。在 UDPSocket.close 后将解除对其的强引用,让 UDPSocket 实例遵从 GC
UDPSocket.onClose(function callback) 监听关闭事件
UDPSocket.offClose(function callback) 取消监听关闭事件
UDPSocket.onError(function callback) 监听错误事件
UDPSocket.offError(function callback) 取消监听错误事件
UDPSocket.onListening(function callback) 监听开始监听数据包消息的事件
UDPSocket.offListening(function callback) 取消监听开始监听数据包消息的事件
UDPSocket.onMessage(function callback) 监听收到消息的事件
UDPSocket.offMessage(function callback) 取消监听收到消息的事件

错误:

错误码 说明
-1 系统错误
-2 socket接口错误,可参考系统的socket错误码
-3 发送失败,无接口权限
1 发送失败,参数错误,address不合法
2 发送失败,参数错误,port不合法

信息链接:

1.微信小程序UDP通信
2.微信官方文档-UDP通信
3.关于微信小程序使用UDP实现局域网通讯及UDP模块的封装
4.关于微信小程序使用UDP实现局域网通讯及UDP模块的封装的个人博客 所提供的 tool.js 封装了常用函数