2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > ESP8266基于MicroPython的TCP socket回调函数实现案例

ESP8266基于MicroPython的TCP socket回调函数实现案例

时间:2021-03-22 01:35:01

相关推荐

ESP8266基于MicroPython的TCP socket回调函数实现案例

参考链接

其它参考

python socket和简单tcp通信实现 - Katherina.K - 博客园

GitHub - robert-hh/FTP-Server-for-ESP8266-ESP32-and-PYBD: Small FTP server for ESP8266/ESP32/PYBD on the MicroPython platform

引用:对于不让 socket 套接字阻塞 micropython 主进程的方法。通常的做法是启动一个socket套接字专属的线程来 accept 和 recv 因为有些开发版(例如esp8266)是不支持多线程的,网上有说可以用_thread实现多线程的,但是查了一些这个指令好像是用于cpython的,并不能跑在ESP8266上,而且一直挂着个线程对于某些需要低功耗的场景来说显然是不明智的。上述文章作者在webrepl 的代码中找到了通过回调函数实现的方式,核心代码如下,其中这个 20 的值是 micropython开发组自己定义的, 主要的功能就是给 socket 套接字绑定一个回调函数

listen_s.setsockopt(socket.SOL_SOCKET, 20, callback)

参考上述思路,自己编写了一个demo程序,client_demo3.py,实现效果为,ESP8266作为TCP client端,具有服务器掉线重连功能,每隔2秒往服务器发送一个255以内的随机数,同时接受服务器控制指令,如果为“on”则打开ESP8266上的灯,为“off”则关灯,其它指令不动作

基本库引用和设置

import socketimport timeimport urandomfrom machine import Pinp2 = Pin(2, Pin.OUT)SERVER_IP = "192.168.1.101"SERVER_PORT = 8080BUFFER_SIZE = 1024

通过回调函数实现服务器数据下控功能,下面是定义socket介绍数据时的回调函数

#定义接收服务器指令的回调函数,下面是打开ESP8266上led灯的指令def receiveHandler(sck: socket.socket()):cmdInfo = sck.recv(BUFFER_SIZE).decode("utf8")if cmdInfo == "on":p2.off()print("Led Opened!")if cmdInfo == "off":p2.on()print("Led Closed!")

socket的基本设置,回调函数绑定

#套接字基本设置及连接操作def doConnect(serverIp, serverPort):#创建套接字,socket.AF_INET表示服务器之间网络通信;socket.SOCK_STREAM表示流式socket,for TCPs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)address = (serverIp, serverPort)#下面是socket对象绑定了一个回调函数,这样不会因为套接字阻塞(如,未收到服务器端信息)而影响micropython主进程#当接收到指令后,则打断现行的操作,运行回调函数,之后自动回到之前的代码,下面的20不要更改s.setsockopt(socket.SOL_SOCKET, 20, receiveHandler)try:#说明,如果下面的连接失败,正常会有报错,这里用pass指令掉过报错s.connect(address)print("Server connected!")except:passreturn s

主函数定义,包含每隔2秒发送随机数,服务器断线重现功能

def main(serverIp = SERVER_IP, serverPort = SERVER_PORT):sConnect = doConnect(serverIp, serverPort)while True:try:#下述指令表示生产一个8位数的整数,这个8位指的是2进制的8个位,最大为255#下面代码是每隔2秒往服务器端发送一个255以内的随机数randomNum = str(urandom.getrandbits(8))sConnect.send(randomNum+"\n")print("随机数: ", randomNum)time.sleep_ms(2000)#下面代码用于处理发送失败事件,正常产生失败原因有服务器掉线、发送数据错误等原因#但是下面仅用于显示报错原因和进行服务器断线重连except Exception as err:print("Excepetion Info: ", err)print("Re connect...")time.sleep_ms(3000)sConnect = doConnect(serverIp, serverPort)

在main.py程序调用上述客户端

import client_demo3client_demo3.main("192.168.1.101", 8080)

代码运行后即可实现与规划功能,效果如下图所示

client_demo3.py完整代码如下

import socketimport timeimport urandomfrom machine import Pinp2 = Pin(2, Pin.OUT)SERVER_IP = "192.168.1.101"SERVER_PORT = 8080BUFFER_SIZE = 1024#定义接收服务器指令的回调函数,下面是打开ESP8266上led灯的指令def receiveHandler(sck: socket.socket()):cmdInfo = sck.recv(BUFFER_SIZE).decode("utf8")if cmdInfo == "on":p2.off()print("Led Opened!")if cmdInfo == "off":p2.on()print("Led Closed!")#套接字基本设置及连接操作def doConnect(serverIp, serverPort):#创建套接字,socket.AF_INET表示服务器之间网络通信;socket.SOCK_STREAM表示流式socket,for TCPs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)address = (serverIp, serverPort)#下面是socket对象绑定了一个回调函数,这样不会因为套接字阻塞(如,未收到服务器端信息)而影响micropython主进程#当接收到指令后,则打断现行的操作,运行回调函数,之后自动回到之前的代码,下面的20不要更改s.setsockopt(socket.SOL_SOCKET, 20, receiveHandler)try:#说明,如果下面的连接失败,正常会有报错,这里用pass指令掉过报错s.connect(address)print("Server connected!")except:passreturn sdef main(serverIp = SERVER_IP, serverPort = SERVER_PORT):sConnect = doConnect(serverIp, serverPort)while True:try:#下述指令表示生产一个8位数的整数,这个8位指的是2进制的8个位,最大为255#下面代码是每隔2秒往服务器端发送一个255以内的随机数randomNum = str(urandom.getrandbits(8))sConnect.send(randomNum+"\n")print("随机数: ", randomNum)time.sleep_ms(2000)#下面代码用于处理发送失败事件,正常产生失败原因有服务器掉线、发送数据错误等原因#但是下面仅用于显示报错原因和进行服务器断线重连except Exception as err:print("Excepetion Info: ", err)print("Re connect...")time.sleep_ms(3000)sConnect = doConnect(serverIp, serverPort)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。