在上一章节中,我们学习了TCPClient通信测试的相关知识。接下来,本章节将以此为基础,构建一个基础性的TCPServer连接机制,该机制将利用之前所建立的WIFI网络连接。为方便演示,我们将借助网络调试助手工具进行数据的发送,进而对网络通信中接收到的数据进行测试,确保这些数据能够准确无误地回传,以验证通信机制的有效性和稳定性。
本节课目标:
基于ESP32开发板的WiFi网络,实现一个简单的TCPServer连接,通过网络调试助手发送数据,并将接收到的数据原原本本地返回。
本节课内容:
- network 与 socket 库的简介
- network库的构造与方法
- socket 库的构造与方法
- 硬件设计
- 软件设计
- 下载验证
一、network 与 socket 库的简介
MicroPython 的 network 库与 socket 库皆为实现网络连接的重要工具,它们各自拥有独特的功能性并共享某些共通特点。
作为 MicroPython 的一个关键第三方库,network 库专门负责处理 WiFi 和网络连接的各项任务。通过此库,用户能够成功接入无线网络,查询当前网络状态,以及实现数据的收发等功能。在 MicroPython 的架构下,network 库扮演着促进设备间网络连接与通信的核心角色。
至于 network 库与 socket 库之间的主要差异,则体现在它们的应用场景与功能侧重上。具体而言,network 库侧重于设备的 WiFi 和基础网络连接功能的实现,而 socket 库则聚焦于高级网络协议的连接建立与数据传输过程。因此,在实际进行网络连接功能的设计与实施时,需根据具体需求及所依赖的硬件平台,谨慎选择并合理运用相应的库资源。
下面是MicroPython库的network 与 socket 库的链接。
network — 网络配置 — MicroPython latest documentation
socket – 套接字模块 — MicroPython latest documentation
类 WLAN – 控制内置 WiFi 接口 — MicroPython 最新文档
二、network.WLAN类的构造与方法
1. network.WLAN类的构造
构造对象方法如下:
class network.WLAN(interface_id)
使用示例:wlan = network.WLAN(network.STA_IF)
参数描述如下:
| 参数 | 描述 | 
| interface_id | 支持接口 
 | 
返回值:WLAN网络接口对象
2. network.WLAN类的方法
(1)激活或停用网络接口
其方法原型如下:
WLAN.active(is_active[ ])
参数描述如下:
| 参数 | 描述 | 
| is_active | 
 | 
返回值:无
(2)连接网络
其方法原型如下:
WLAN.connect(ssid=None, password=None)
参数描述如下:
| 参数 | 描述 | 
| ssid | WiFi账号 | 
| password | WiFi密码 | 
返回值:Ture:连接成功;Fail:连接失败。
(3)关闭网络
其方法原型如下:
WLAN.disconnet()
返回值:无
(4)获取或者设置网络参数
其方法原型如下:
WLAN.ifconfig((ip, subnet, gateway, dns)[])
参数描述如下:
| 参数 | 描述 | 
| ip | IP地址 | 
| subnet | 子网掩码 | 
| gateway | 网关 | 
| dns | DNS服务器 | 
返回值:若此函数为无参数传入,则返回连接网络的信息,反次,为设置网络参数。
以上是 network.WLAN 类常用的方法,还有其他方法可参考 MicroPython 的在线文档。
三、socket 库的构造与方法
1. socket类的构造
构造对象方法如下:
class socket.socket(af=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP, /)
使用示例:socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
参数描述如下:
| 参数 | 描述 | 
| af | 地址族 
 | 
| type | socket类型 
 | 
| proto | 网络协议 
 | 
返回值:socket对象
2. socket类的方法
(1)关闭socket接口
其方法原型如下:
socket.close()
返回值:无
(2)设置socket 选项的值
其方法原型如下:
socket.setsockopt(level, optname, value)
参数描述如下:
| 参数 | 描述 | 
| level | 是被设置的选项的级别,如果想要在套接字级别上设置选项,就必须把level设置为 | 
| optname | 在套接字级别上(SOL_SOCKET),option_name可以有以下取值: 
 | 
| value | True:开启;False:关闭 | 
返回值:无
(3)socket绑定到地址
其方法原型如下:
socket.bind(address)
参数描述如下:
| 参数 | 描述 | 
| address | IP地址(字符串形式输入,如‘192.168.1.100’) | 
返回值:无
(4)监听连接
用作于 TCPServer 连接。
其方法原型如下:
socket.listen(backlog[])
参数描述如下:
| 参数 | 描述 | 
| backlog | 监听连接数量 | 
返回值:无
(5)接受连接
用作于 TCPServer 连接。注:在此之前,需监听连接
其方法原型如下:
socket.accept()
返回值:conn:新的套接字对象,用来收发消息;address:连接到服务器的客户端地址。
(6)连接远程IP地址
其方法原型如下:
socket.connect(address)
参数描述如下:
| 参数 | 描述 | 
| address | IP地址(字符串形式输入,如‘192.168.1.100’) | 
返回值:无
(7)发送数据,返回发送的字节数
其方法原型如下:
socket.send(bytes)
参数描述如下:
| 参数 | 描述 | 
| bytes | 需发送的字节数据 | 
返回值:发送的数据字节数。
(8)接收数据,返回值是一个字节对象
其方法原型如下:
socket.recv(bufsize)
参数描述如下:
| 参数 | 描述 | 
| bufsize | 接收数据的存储区 | 
返回值:接收数据字节对象。
(9)接收数据,返回值是一个字节对象
其方法原型如下:
socket.recvfrom(bufsize)
参数描述如下:
| 参数 | 描述 | 
| bufsize | 接收数据的存储区 | 
返回值:bytes:接收数据字节对象;addressa:套接字发送的地址数据。
(10)UDP发送数据,一般用于UDP连接
其方法原型如下:
socket.sendto(bytes, address)
参数描述如下:
| 参数 | 描述 | 
| bytes | 发送的数据 | 
| address | 发送至哪个远程IP地址 | 
返回值:发送的数据字节数。
以上方法列出了本书中常用的套接字方法,对于剩余的套接字方法,请参考MicroPython最新的在线文档。
四、硬件设计
1. 例程功能
在本次实验中,我们将ESP32开发板与WiFi网络进行了连接,并完成了TCPServer的连接配置。当TCPServer成功建立连接后,我们采用了网络调试助手作为客户端设备,而开发板则作为服务器端设备。在此环境下,当客户端设备(即网络调试助手)向服务器端设备(即开发板)发送数据时,服务器端设备将接收到的数据完整地回传至客户端设备,从而实现了数据的双向交互。
2. 硬件资源
- WIFI :ESP32内部自带WIFI模块
四、软件设计
1. 程序流程图

2. 程序
import network
import socket
# 网络信息
SSID = 'OrayBox-zsf'                # WIFI名称
PASSWORD = '123456789'              # WIFI密码
Server_IP = '10.168.1.164'          # 服务器IP地址
wlan = None                         # 定义一个无线网络
pos = 0                             # 状态机,用于状态切换
def connect():
    """
    连接 WIFI 路由器
    """
    global wlan
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        print('connecting to network...')
        wlan.connect(SSID, PASSWORD)
        while not wlan.isconnected():
            pass
    print('network config:', wlan.ifconfig())       # 打印网络参数
def goto(label):
    """
    切换状态
    :param label: 状态号
    """
    global pos
    pos = label
"""
------------------------------------------------------------------------------------
                                    下面为主函数
------------------------------------------------------------------------------------
"""
# 1、连接 WIFI 路由器
connect()
while True:
    # 循环
    while pos == 0:                             # 状态 0 : 用于建立socket,连接服务器
        # 2、获取本地 IP 地址,并打印
        ip = wlan.ifconfig()[0]
        print('network config:', ip)
        # 3、创建 TCP 套接字
        TCPServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)       # 创建 TCPServer 对象,IPV4 \ TCP 类型
        # 4、绑定 本地IP 和 端口号
        # 设置端口复用,是用来设置套接字选项的函数调用。这个选项用于指定套接字的行为,打开地址复用功能,以便在绑定到一个端口时,能够重新使用这个端口。否则会出错
        TCPServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        TCPServer.bind(('', 8080))
        # 5、监听,参数是同时连接的客户端数量
        TCPServer.listen(10)
        # 6、阻塞等待客户端连接
        # 返回一个元组 (新 socket, (客户端 IP,端口) )
        try:
            new_socket, client_ip_port = TCPServer.accept()       # 连接服务器
        except BaseException:
            # 故障处理程序
            new_socket.close()                          # 关闭新套接字
            TCPServer.close()                           # 关闭套接字
            print(' 关闭套接字.... ')
            goto(0)                                     # 重新返回状态 0
            break
        else:
            print('连接建立成功......')
            new_socket.send('************** ESP32 服务器: '.encode() + str(ip).encode() + ' 欢迎你!!! ****************\r\n'.encode())
            goto(1)                                     # 进入状态 1:网络连接成功,处理通信
    while pos == 1:
        # 状态 1 : 用于连接服务器后,发送接收到的服务器数据
        try:
            # 接收到客户端的数据
            data = new_socket.recv(1024)
            print(data.decode())
        except BaseException:
            # 故障时,关闭连接,重新建立连接
            new_socket.close()
            TCPServer.close()                       # 关闭套接字
            goto(0)
            break
        else:
            # 空数据时,不回显
            if (len(data) == 0):
                print('接收到空的数据')
                new_socket.close()
                TCPServer.close()  # 关闭套接字
                goto(0)
                break
            else:
                # 非空数据回显
                new_socket.send(data)
五、下载验证
将ESP32开发板与电脑通过WIFI路由器,连接在同一WiFi网络中,配置电脑上的网络调试助手TCP Client参数,如下图所示,并连接服务器网络,将接收到ESP32开发板服务器发送过来的数据。

与ESP32通过TCP协议相互通信。




















![[Python]案例驱动最佳入门:Python数据可视化在气候研究中的应用](https://i-blog.csdnimg.cn/direct/788c4b4e3bda4bcda1b551c1909817ea.jpeg)