7. HTTP-Client例程讲解#
1. 环境准备#
首先,确保你的CanMV开发板已经通过网口与路由器或交换机相连,并且路由器能够正常工作,具备访问互联网的能力。这是进行HTTP请求的基础环境设置。
2. 例程详解#
下面的Python例程展示了如何在CanMV开发板上实现一个简单的HTTP客户端,用于向指定的服务器(本例中为百度)发送HTTP GET请求,并接收响应内容。
2.1 导入必要的模块#
import network
import socket
这里导入了network
和socket
两个模块。network
模块用于管理网络接口,而socket
模块则提供了网络通信的底层接口。
2.2 定义主函数#
def main(use_stream=True):
# ...(后续代码)
定义了一个名为main
的函数,它接受一个名为use_stream
的参数,默认为True
。这个参数用于控制是否使用流式接口来读取响应数据。
2.3 配置网络接口#
def network_use_wlan(is_wlan=True):
if is_wlan:
sta=network.WLAN(0)
sta.connect("Canaan","Canaan314")
print(sta.status())
while sta.ifconfig()[0] == '0.0.0.0':
os.exitpoint()
print(sta.ifconfig())
ip = sta.ifconfig()[0]
return ip
else:
a=network.LAN()
if not a.active():
raise RuntimeError("LAN interface is not active.")
a.ifconfig("dhcp")
print(a.ifconfig())
ip = a.ifconfig()[0]
return ip
这段代码根据输入参数来配置网络接口。主要流程如下:
WLAN模式:
如果
is_wlan
参数为True
,则程序配置无线网络接口(WLAN)。创建 WLAN 接口实例并尝试连接到指定的 Wi-Fi 网络(SSID 为 “Canaan”,密码为 “Canaan314”)。
打印 WLAN 接口的连接状态,并在获得有效 IP 地址之前循环等待。
成功连接后,打印网络配置并返回获取的 IP 地址。
LAN模式:
如果
is_wlan
参数为False
,则程序配置有线网络接口(LAN)。获取 LAN 接口实例并检查其是否已激活。
如果接口未激活,抛出
RuntimeError
异常,提示接口未激活。将 LAN 接口配置为 DHCP 模式,自动从路由器获取 IP 地址。
打印网络配置并返回获取的 IP 地址。
2.4 创建并配置socket#
# 创建socket对象
s = socket.socket()
# 尝试获取目标地址和端口号
ai = []
for attempt in range(0, 3):
try:
ai = socket.getaddrinfo("www.baidu.com", 80)
break
except:
print("getaddrinfo again")
# 检查是否成功获取地址信息
if ai == []:
print("连接错误")
s.close()
return
# 提取地址和端口号
addr = ai[0][-1]
print("连接地址:", addr)
这段代码首先创建了一个socket对象,然后尝试通过getaddrinfo
函数获取目标服务器(百度)的地址和端口号信息。为了提高代码的健壮性,这里使用了重试机制,最多尝试3次。如果成功获取到地址信息,则提取出地址和端口号,并打印出来。
2.5 发送HTTP请求并接收响应#
# 连接到服务器
s.connect(addr)
if use_stream:
# 使用流式接口读取响应
s = s.makefile("rwb", 0)
s.write(b"GET /index.html HTTP/1.0\r\n\r\n")
print(s.read())
else:
# 直接使用socket接口发送和接收数据
s.send(b"GET /index.html HTTP/1.0\r\n\r\n")
print(s.recv(4096))
# 关闭socket
s.close()
这部分代码首先连接到服务器,然后根据use_stream
参数的值选择使用流式接口还是直接通过socket接口发送HTTP请求。如果use_stream
为True
,则使用流式接口发送请求并读取整个响应;如果为False
,则直接发送请求并接收一定长度的响应数据(本例中为4096字节)。最后,关闭socket连接以释放资源。
2.6 函数调用#
# 调用主函数,分别测试流式接口和非流式接口
main(use_stream=True)
main(use_stream=False)
最后,通过调用main
函数并传入不同的use_stream
参数值,可以分别测试流式接口和非流式接口的效果。这样可以帮助你更好地理解这两种方式在读取HTTP响应时的差异。
2.7 完整例程#
import network
import socket
import os,time
def network_use_wlan(is_wlan=True):
if is_wlan:
sta=network.WLAN(0)
sta.connect("Canaan","Canaan314")
print(sta.status())
while sta.ifconfig()[0] == '0.0.0.0':
os.exitpoint()
print(sta.ifconfig())
ip = sta.ifconfig()[0]
return ip
else:
a=network.LAN()
if not a.active():
raise RuntimeError("LAN interface is not active.")
a.ifconfig("dhcp")
print(a.ifconfig())
ip = a.ifconfig()[0]
return ip
def main(use_stream=True):
#获取lan接口
network_use_wlan(True)
#创建socket
s = socket.socket()
#获取地址及端口号 对应地址
ai = []
for attempt in range(0, 3):
try:
#获取地址及端口号 对应地址
ai = socket.getaddrinfo("www.baidu.com", 80)
break
except:
print("getaddrinfo again");
if(ai == []):
print("connet error")
s.close()
return
print("Address infos:", ai)
addr = ai[0][-1]
print("Connect address:", addr)
#连接
s.connect(addr)
if use_stream:
# MicroPython socket objects support stream (aka file) interface
# directly, but the line below is needed for CPython.
s = s.makefile("rwb", 0)
#发送http请求
s.write(b"GET /index.html HTTP/1.0\r\n\r\n")
#打印请求内容
print(s.read())
else:
#发送http请求
s.send(b"GET /index.html HTTP/1.0\r\n\r\n")
#打印请求内容
print(s.recv(4096))
#print(s.read())
#关闭socket
s.close()
#main()
main(use_stream=True)
main(use_stream=False)