【MaixPy系列教程:】
在教程开始之前你需要了解套接字、和tcp协议及编程的原理:
什么是套接字?
Socket
是网络编程的一个抽象概念。通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可。
TCP协议简介
TCP协议,传输控制协议(Transmission Control Protocol,缩写为 TCP)是一种面向连接的、可靠的、基于字节流的传输层通讯协议,由IETF的RFC 793定义。
TCP通信需要经过创建连接、数据传送、终止连接三个步骤。TCP通信模型中,在通信开始之前,一定要先创建相关连接,才能发送数据,类似于生活中,“打电话”"。
套接字在工作时将连接的双方分为服务器端和客户端,即C/S模式,TCP通讯原理如下图:
整体思路:
用掌控板来做TCP服务器,MixNo 来做TCP客户端。(创建TCP连接时,主动发起连接的叫客户端,被动响应连接的叫服务器)首先我们先用mpython编写程序为掌控板写TCP客户端来显示客户端的请求,用mixly【软件关注童芯创悟进行获取】编写MixNo的TCP客户端,向服务端发送消息
TCP编程的服务端一般步骤是:
创建一个socket,用函数socket()
设置socket属性,用函数setsockopt() , 可选
绑定IP地址、端口等信息到socket上,用函数bind()
开启监听和设置最大监听数,用函数listen()
等待客户端請求一个连接,用函数accept()
收发数据,用函数send()和recv(),或者read()和write()
关闭网络连接
首先打开mpython,先让配置掌控板的网络(可以是sta模式,或者AP模式),然后套接字初始化。:
# 套接字初始化
socket(socket_family, socket_type, protocol)
# socket_family 就是指套接字家族可以是AF_UNIX(基于文件的)或AF_INET(基于网络的)(IPV4)AF_INET6(IPV6)
#socket_type 就是指套接字类型,即SOCK_STREAM(TCP协议)或SOCK_DGRAM(UDP协议)
#protocol 是协议,默认为0,一般不填
mywifi.sta.ifconfig() 用于获得当前链接网络的静态IP地址信息,返回类型为4元素元组,我們用元组中的第一项来做服务器的IP地址。
IP地址:192.168.0.4
NETMASK(子网掩码): 255.255.255.0
GATEWAY(网关):192.168.0.1
DNS:类似本地的host文件。公网DNS注册域名。
注意:返回的数据是一个4元组,元组中的每一项都是字符串格式。
conn,addr = listenSocket.accept()
# 阻塞,等待客户端的请求连接,如果有新的客户端来连接服務器,那麼会返回一个新的套接字专门为这个客户端服务
需要注意的是:在服务器未接收到任何客户端的访问请求时,程序将停留在该位置,只有有新的请求产生时,程序才能向下进行。所以,如果掌控板在这种情况下,需要处理一些实时程序的话,需要建立定时器中断和外部中断,否则无法对自定义程序进行有效处理。
ocket.recv()接收客户端发来的数据。最大数据量是1024
注意:socket.recv()接收到的数据是二进制字符串格式(与正常的字符串有些差别,需要使用decode()函数来将其解码转化为正常的字符串)
TCP编程的客户端一般步骤是:
1、创建一个socket,用函数socket()
2、设置socket属性,用函数setsockopt() , 可选
3、绑定IP地址、端口等信息到socket上,用函数bind() , 可选
4、设置要连接的对方的IP地址和端口等属性
5、连接服务器,用函数connect()
6、收发数据,用函数send()和recv(),或者read()和write()
7、关闭网络连接
首先打开mixly,设置MixNo需要连接的wifi网络(和服务器同一网络),初始化套接字:
客户端有了套接字后,马上就可以调用connect()函数去连接服务器(ps:以元组或者列表的方式绑定服务器地址,和端口)。
建立连接后,就可以与服务器开始对话。在对话结束后,客户端就可以关闭套接字,结束连接。
# tcp服务器代码
import socket
from mpython import *
port=5001 # TCP服务端的端口,range0~65535
listenSocket=None
mywifi=wifi() # 创建wifi类
# 捕获异常,如果在"try" 代码块中意外中断,则停止关闭套接字
try:
mywifi.connectWiFi("ssid","password") # WiFi连接,设置ssid 和password
# mywifi.enable_APWiFi("wifi_name",13) # 还可以开启AP模式,自建wifi网络
ip= mywifi.sta.ifconfig()[0] # 获取本机IP地址
listenSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建socket,不给定参数默认为TCP通讯方式
listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 设置套接字属性参数
listenSocket.bind((ip,port)) # 绑定ip和端口
listenSocket.listen(3) # 开始监听并设置最大连接数
print ('tcp waiting...')
oled.DispChar("%s:%s" %(ip,port),0,0) # oled屏显示本机服务端ip和端口
oled.DispChar('accepting.....',0,16)
oled.show()
while True:
print("accepting.....")
conn,addr = listenSocket.accept() # 阻塞,等待客户端的请求连接,如果有新的客户端来连接服務器,那麼会返回一个新的套接字专门为这个客户端服务
print(addr,"connected")
while True:
data = conn.recv(1024) # 接收对方发送过来的数据,读取字节设为1024字节
if(len(data) == 0):
print("close socket")
conn.close() # 如果接收数据为0字节时,关闭套接字
break
data_utf=data.decode() # 接收到的字节流以utf8编码解码字符串
print(data_utf)
oled.DispChar(data_utf,0,48) # 将接收到文本oled显示出来
oled.show()
oled.fill_rect(0,48,128,16,0) # 局部清屏
conn.send(data) # 返回数据给客户端
# 当捕获异常,关闭套接字、网络
except:
if(listenSocket):
listenSocket.close()
mywifi.disconnectWiFi()
# tcp客户端代码程序
import time
import socket
import network_no
import machine
try:
nic = network_no.wifi_init1()
nic.connect("hockel","erised88")
print(nic.ifconfig())
sock = socket.socket()
sock.settimeout(5)
sock.connect(("192.168.43.246", 5001))
while True:
sock.send("Hello Handbit")
time.sleep_ms(1000)
sock.send("I'am MixNo")
time.sleep_ms(1000)
except:
sock.close()
小结:
有了TCP通讯后,就可以把MixNo识别到的物体发送到掌控板上了,掌控板可以对发来的消息进行处理做出相应的动作(比如:口罩识别门禁,人体追踪、颜色识别等等,当然这些在MixNo中也可以独自完成)。
首发个人博客:www.hockel.club,欢迎关注哈。有问题的可以加入【MixNo QQ群:1056344043】