【雕爷学编程】MicroPython手册之 WiPy FTP 服务器

在这里插入图片描述
MicroPython是为了在嵌入式系统中运行Python 3编程语言而设计的轻量级版本解释器。与常规Python相比,MicroPython解释器体积小(仅100KB左右),通过编译成二进制Executable文件运行,执行效率较高。它使用了轻量级的垃圾回收机制并移除了大部分Python标准库,以适应资源限制的微控制器。

MicroPython主要特点包括:
1、语法和功能与标准Python兼容,易学易用。支持Python大多数核心语法。
2、对硬件直接访问和控制,像Arduino一样控制GPIO、I2C、SPI等。
3、强大的模块系统,提供文件系统、网络、图形界面等功能。
4、支持交叉编译生成高效的原生代码,速度比解释器快10-100倍。
5、代码量少,内存占用小,适合运行在MCU和内存小的开发板上。
6、开源许可,免费使用。Shell交互环境为开发测试提供便利。
7、内置I/O驱动支持大量微控制器平台,如ESP8266、ESP32、STM32、micro:bit、掌控板和PyBoard等。有活跃的社区。

MicroPython的应用场景包括:
1、为嵌入式产品快速构建原型和用户交互。
2、制作一些小型的可 programmable 硬件项目。
3、作为教育工具,帮助初学者学习Python和物联网编程。
4、构建智能设备固件,实现高级控制和云连接。
5、各种微控制器应用如物联网、嵌入式智能、机器人等。

使用MicroPython需要注意:
1、内存和Flash空间有限。
2、解释执行效率不如C语言。
3、部分库函数与标准版有差异。
4、针对平台优化语法,订正与标准Python的差异。
5、合理使用内存资源,避免频繁分配大内存块。
6、利用原生代码提升速度关键部位的性能。
7、适当使用抽象来封装底层硬件操作。

总体来说,MicroPython让Python进入了微控制器领域,是一项重要的创新,既降低了编程门槛,又提供了良好的硬件控制能力。非常适合各类物联网和智能硬件的开发。
在这里插入图片描述
WiPy是一款基于MicroPython的无线微控制器模块,它提供了一个完整的硬件和软件解决方案,旨在简化物联网(IoT)设备的开发和部署。

1、微控制器模块:WiPy是一种集成了处理器、内存、无线通信模块和其他必要组件的微型计算机模块。它的设计目标是提供一个紧凑、低功耗的硬件平台,能够运行MicroPython这样的高级编程语言,并具备连接到互联网和其他设备的能力。
2、MicroPython:MicroPython是一种精简版的Python编程语言,专为嵌入式系统和微控制器设计而开发。它提供了Python语言的核心功能和语法,使得开发者能够使用熟悉的Python语法进行硬件控制和物联网应用开发。WiPy作为MicroPython的运行环境,能够直接解释和执行MicroPython代码。
3、物联网(IoT):物联网是指将各种物理设备(如传感器、执行器、嵌入式系统等)通过互联网连接起来,实现智能化、互联互通的网络。WiPy作为一种无线微控制器模块,具备无线通信能力,能够连接到物联网中的其他设备和云平台,实现远程控制和数据交换。
4、无线通信模块:WiPy内置了一种或多种无线通信模块,常见的包括Wi-Fi、蓝牙(Bluetooth)和LoRa等。这些无线通信模块使得WiPy能够通过无线网络与其他设备进行通信,实现数据传输、远程控制、云连接等功能。开发者可以根据具体需求选择适合的无线通信模块。
5、开发和部署:WiPy提供了一套方便的开发工具和开发环境,使得开发者能够快速进行应用程序的开发、调试和测试。开发完成后,WiPy可以直接部署到实际的物联网设备中,与其他设备进行通信和交互。WiPy的紧凑设计和低功耗特性,使得它非常适合嵌入式系统和物联网设备的部署。

在这里插入图片描述
MicroPython的WiPy FTP服务器是一种基于FTP协议的服务器功能,用于文件传输和管理。

主要特点:

文件传输功能:WiPy FTP服务器提供了文件传输功能,使得用户可以通过FTP客户端与WiPy设备进行文件的上传、下载和管理。用户可以通过FTP协议在本地计算机和WiPy设备之间传输文件。
简单易用:WiPy FTP服务器使用简单,通过配置和启动FTP服务器,即可实现文件传输。用户可以使用标准的FTP客户端软件(如FileZilla)连接到WiPy设备,并进行文件操作。
灵活性和可扩展性:WiPy FTP服务器基于MicroPython语言,具有灵活性和可扩展性。用户可以编写自定义的FTP功能和文件管理逻辑,根据具体需求扩展和定制WiPy设备的文件传输能力。

应用场景:

固件升级和文件更新:WiPy FTP服务器可用于固件升级和文件更新。将新的固件或文件上传到WiPy设备,实现设备功能的更新和升级。
数据采集和日志传输:WiPy FTP服务器适用于数据采集和日志传输应用。将采集到的数据或设备日志通过FTP传输到本地计算机或远程服务器,进行后续的数据分析和处理。
远程文件管理:WiPy FTP服务器可以用于远程文件管理。通过FTP客户端远程连接到WiPy设备,实现文件的上传、下载、删除和重命名等操作,方便对设备中的文件进行管理。

注意事项:

安全性:WiPy FTP服务器使用明文传输,不提供加密功能,因此需要注意安全性。建议在安全的网络环境中使用,或者通过其他安全机制(如VPN)对FTP连接进行加密保护。
访问控制:为了保护WiPy设备的安全性,需要设置适当的访问控制措施,如设置FTP访问密码、限制访问IP等,以防止未经授权的访问。
文件权限:在使用WiPy FTP服务器时,需要注意文件权限的设置。确保只有授权的用户可以访问和操作特定的文件,避免文件的非授权访问和篡改。

综上所述,MicroPython的WiPy FTP服务器提供了文件传输和管理的功能,适用于固件升级、数据采集、远程文件管理等场景。在使用WiPy FTP服务器时,需要注意安全性、访问控制和文件权限等方面,以确保文件传输的安全和可靠性。

在这里插入图片描述

案例1:使用MicroPython创建FTP服务器

from machine import Pin, UART
import time
import socket

uart = UART(2, baudrate=9600)
rx_pin = Pin(4, Pin.IN)
tx_pin = Pin(5, Pin.OUT)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 21))
server_socket.listen(1)

print("FTP server is running on port 21...")

while True:
    # 等待客户端连接
    client_socket, client_address = server_socket.accept()
    print("Client connected: {0}".format(client_address))

    # 接收客户端发送的用户名和密码并验证
    data = rx_pin.value()
    if not data:
        break
    username, password = data.decode().split(',')
    if username == 'admin' and password == 'password':
        # 设置文件传输模式为二进制
        client_socket.sendall(b'TYPE I')
        client_socket.sendall(b'MODE O')
        client_socket.sendall(b'STRU CHS \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf3')
        client_socket.sendall(b'PASV')
        client_socket.sendall(b'227 Entering Passive Mode (h1,h2,h3,h4,p1,p2).')
        client_socket.sendall(b'USER admin')
        client_socket.sendall(b'PASS password')
        client_socket.sendall(b'QUIT')

    # 关闭客户端连接
    client_socket.close()

# 关闭连接
server_socket.close()

案例2:使用MicroPython从FTP服务器下载文件

from machine import Pin, UART, SPI
import time
import socket

uart = UART(2, baudrate=9600)
rx_pin = Pin(4, Pin.IN)
tx_pin = Pin(5, Pin.OUT)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.connect(('localhost', 21))

while True:
    # 等待用户输入要下载的文件名
    data = rx_pin.value()
    if not data:
        break
    file_name = data.decode().strip()

    # 发送RETR命令请求文件下载
    tx_pin.value(b'RETR ' + file_name)
    server_socket.sendall(b'OK')

    # 读取文件数据并保存到本地文件
    with open(file_name, 'wb') as f:
        while True:
            chunk = server_socket.recv(16384)
            if not chunk:
                break
            f.write(chunk)

    # 关闭连接
    server_socket.close()

案例3:使用MicroPython向FTP服务器上传文件

from machine import Pin, UART, SPI
import time
import socket

uart = UART(2, baudrate=9600)
tx_pin = Pin(4, Pin.OUT)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 21))
server_socket.listen(1)

print("FTP server is running on port 21...")

while True:
    # 等待用户输入要上传的文件名和FTP服务器上的文件路径
    data = rx_pin.value()
    if not data:
        break
    file_name = data.decode().strip()
    ftp_path = input("Enter the path of the file on the FTP server: ")

    # 发送STOR命令上传文件
    tx_pin.value(b'STOR ' + file_name)
    server_socket.sendall(b'OK')

    # 打开本地文件并读取数据并发送到FTP服务器
    with open(file_name, 'rb') as f:
        while True:
            chunk = f.read(16384)
            if not chunk:
                break
            tx_pin.value(chunk)
            server_socket.sendall(chunk)

    # 关闭连接
    server_socket.close()

案例4:对于MicroPython的WiPy设备,实际上并没有原生的FTP服务器支持。FTP是一种复杂的协议,需要服务器端和客户端两方面的支持,而在MicroPython的WiPy设备上实现FTP服务器可能会相当复杂。

然而,你可以在WiPy设备上运行一个FTP服务器,比如通过使用一些更复杂的嵌入式Python环境(不一定直接在WiPy上,也可以在类似树莓派等更强大的设备上运行Python来作为FTP服务器),或者使用一些专门为这个目的设计的第三方库。

以下是一个基本的FTP服务器的实现例子,使用Python的ftplib库。这并不是使用MicroPython或WiPy的代码,而是在更通用的Python环境(可以在WiPy或其他Python环境中运行)中的代码。你可以参考这个例子来了解如何在Python中实现FTP服务器。

from ftplib import FTP  
  
def start_ftp_server(host, port):  
    ftp = FTP()  
    ftp.connect(host, port)  
    ftp.login(user="username", passwd="password")  # 用实际的用户名和密码替换  
    return ftp  
  
def stop_ftp_server(ftp):  
    ftp.quit()  
  
def main():  
    ftp = start_ftp_server("127.0.0.1", 21)  # FTP的标准端口是21  
    # 这里可以添加处理FTP请求的代码,例如列出文件、获取文件、上传文件等操作  
    stop_ftp_server(ftp)  
  
if __name__ == "__main__":  
    main()

请注意这只是一个最基本的FTP服务器的例子,实际上FTP服务器需要处理很多其他的事情,比如处理用户连接、处理各种FTP命令(如USER, PASS, RETR, STOR等)、处理文件系统等等。如果你需要在MicroPython的WiPy设备上实现FTP服务器,可能需要更详细的指导和专门为MicroPython设计的库来帮助你实现这些功能。

案例5:使用ftplib库创建FTP客户端并连接到FTP服务器的示例代码:

from ftplib import FTP  
  
def connect_to_ftp_server(host, port, username, password):  
    ftp = FTP()  
    ftp.connect(host, port)  
    ftp.login(user=username, passwd=password)  
    return ftp  
  
def list_files_on_ftp_server(ftp):  
    ftp.retrlines('LIST')  
  
def download_file_from_ftp_server(ftp, remote_path, local_path):  
    with open(local_path, 'wb') as fd:  
        ftp.retrbinary('RETR ' + remote_path, fd.write)  
  
def upload_file_to_ftp_server(ftp, local_path, remote_path):  
    with open(local_path, 'rb') as fd:  
        ftp.storbinary('STOR ' + remote_path, fd)  
  
def disconnect_from_ftp_server(ftp):  
    ftp.quit()  
  
def main():  
    ftp = connect_to_ftp_server("127.0.0.1", 21, "username", "password")  
    list_files_on_ftp_server(ftp)  
    download_file_from_ftp_server(ftp, "remote/path", "local/path")  
    upload_file_to_ftp_server(ftp, "local/path", "remote/path")  
    disconnect_from_ftp_server(ftp)  
  
if __name__ == "__main__":  
    main()

请注意,这只是一个示例代码,并未处理可能出现的异常情况。在实际应用中,你需要根据具体的需求和环境进行适当的修改和补充。

案例6:一个使用 uftpd 库来创建一个简单的 FTP 服务器的案例1。uftpd 是一个用于实现 FTP 服务器功能的库,可以在 WiPy 上运行,并允许客户端通过 FTP 协议访问 WiPy 上的文件系统。代码如下:

# 导入 uftpd 库
import uftpd

# 启动 FTP 服务器,监听 21 端口,使用默认的用户名和密码(micro:python)
uftpd.start()

案例7:一个使用 ftplib 库来从 FTP 服务器下载文件的案例。ftplib 是一个用于实现 FTP 客户端功能的库,可以通过网络连接到 FTP 服务器,并与之交互。代码如下:

# 导入 ftplib 库
import ftplib

# 创建一个 FTP 对象,连接到指定的 IP 地址和端口号
ftp = ftplib.FTP('192.168.1.100', 'micro', 'python')

# 切换到要下载文件所在的目录
ftp.cwd('/flash')

# 打开一个本地文件,用于写入
f = open('test.txt', 'w')

# 定义一个回调函数,将从服务器接收的数据写入本地文件
def write_data(data):
    f.write(data)

# 从服务器下载文件,使用回调函数处理数据
ftp.retrlines('RETR test.txt', write_data)

# 关闭本地文件
f.close()

# 关闭 FTP 连接
ftp.quit()

案例8:一个使用 network 库和 socket 库来创建一个自定义的 FTP 服务器的案例。network 是一个用于控制 WiPy 上的网络功能的库,可以创建一个 WLAN 对象,并设置为 STA 或 AP 模式。socket 是一个用于实现网络通信功能的库,可以创建一个监听指定端口的 socket 对象,并接受客户端的连接请求。代码如下:

# 导入 network 库和 socket 库
import network
import socket

# 创建一个 WLAN 对象,设置为 AP 模式
wlan = network.WLAN(mode=network.WLAN.AP, ssid='wipy-ftp', auth=(network.WLAN.WPA2, 'wipy1234'))

# 获取 WiPy 的 IP 地址
ip = wlan.ifconfig()[0]

# 创建一个 socket 对象,设置为 TCP 模式和 IPv4 协议
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定 socket 到 WiPy 的 IP 地址和 21 端口
s.bind((ip, 21))

# 开始监听端口,最多允许 5 个连接
s.listen(5)

# 定义一些常量,表示不同的 FTP 命令和响应
USER = b'USER'
PASS = b'PASS'
QUIT = b'QUIT'
OK = b'200 OK\r\n'
LOGIN = b'230 Login successful\r\n'
BYE = b'221 Goodbye\r\n'
FAIL = b'530 Login incorrect\r\n'

# 循环接受客户端的连接请求
while True:
    # 接受一个连接请求,返回一个客户端 socket 和地址
    client, addr = s.accept()
    # 打印客户端地址
    print('Got a connection from {}'.format(addr))
    # 向客户端发送 OK 响应
    client.send(OK)
    # 定义一个标志变量,表示是否已登录
    logged_in = False
    # 循环接收客户端发送的数据,最多 1024 字节
    while True:
        data = client.recv(1024)
        # 如果数据为空,则跳出循环
        if not data:
            break
        # 将数据按空格分割为列表,例如 b'USER micro' -> [b'USER', b'micro']
        args = data.split()
        # 取出列表的第一个元素作为命令名,例如 b'USER'
        cmd = args[0]
        # 如果命令为 USER,则检查用户名是否为 micro
        if cmd == USER:
            if args[1] == b'micro':
                # 如果用户名正确,则向客户端发送 OK 响应
                client.send(OK)
            else:
                # 如果用户名错误,则向客户端发送 FAIL 响应,并跳出循环
                client.send(FAIL)
                break
        # 如果命令为 PASS,则检查密码是否为 python
        elif cmd == PASS:
            if args[1] == b'python':
                # 如果密码正确,则向客户端发送 LOGIN 响应,并设置标志变量为 True
                client.send(LOGIN)
                logged_in = True
            else:
                # 如果密码错误,则向客户端发送 FAIL 响应,并跳出循环
                client.send(FAIL)
                break
        # 如果命令为 QUIT,则向客户端发送 BYE 响应,并跳出循环
        elif cmd == QUIT:
            client.send(BYE)
            break
        # 如果已登录,则根据不同的命令执行相应的操作,例如列出文件,上传文件,下载文件等
        elif logged_in:
            # 这里省略了具体的实现细节,可以参考 FTP 协议的规范
            pass
        # 如果未登录,则向客户端发送 FAIL 响应,并跳出循环
        else:
            client.send(FAIL)
            break
    # 关闭客户端 socket
    client.close()

请注意,以上案例只是为了拓展思路,可能存在错误或不适用的情况。不同的硬件平台、使用场景和MicroPython版本可能会导致不同的使用方法。在实际编程中,您需要根据您的硬件配置和具体需求进行调整,并进行多次实际测试。确保正确连接硬件并了解所使用的传感器和设备的规范和特性非常重要。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41659040/article/details/133414647