TCP Server 例程讲解#
例程位置#
开发板固件路径:
/sdcard/examples/14-Socket/tcp_server.pySDK 源码路径:
src/canmv/resources/examples/14-Socket/tcp_server.py
该例程把开发板作为 TCP 服务端,在 8080 端口等待连接,向客户端发送欢迎消息,
并回显收到的数据。
运行前准备#
在脚本顶部配置联网方式:
NETWORK_TYPE = "wifi_sta" # "default"、"lan"、"wifi_sta" 或 "wifi_ap"
WLAN_DEVICE = "auto" # "auto"、"usb"、"sdio" 或 "spi"
WIFI_SSID = "TEST"
WIFI_PASSWORD = "12345678"
NETWORK_TIMEOUT = 20
电脑端需要 TCP 客户端或网络调试工具,并且能够访问开发板取得的 IP。
代码流程#
联网并取得 IP#
netif, ip = connect_network(...)
连接成功后,ip 会用于输出 tcp server <IP> port:8080,这是客户端应连接的地址。
创建并配置监听 Socket#
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
addr = socket.getaddrinfo("0.0.0.0", 8080)[0][-1]
s.bind(addr)
s.settimeout(0)
s.listen(5)
SOCK_STREAM创建 TCP Socket。SO_REUSEADDR便于脚本重启后重新绑定同一端口。0.0.0.0监听所有 IPv4 接口,不依赖动态 netdev 名称。settimeout(0)使用非阻塞模式,等待期间仍可调用os.exitpoint()响应退出。
接受连接#
client_sock, client_addr = s.accept()
client_sock.setblocking(False)
没有待处理连接时,非阻塞 accept() 可能返回 errno == 11,例程会继续等待。连接
建立后会打印客户端地址,并发送一条包含连接计数的欢迎消息。
读取并回显数据#
h = client_stream.read()
if h is None:
continue
if h != b"":
print(h)
client_stream.write("recv :%s" % h)
None 表示当前暂时没有数据;非空数据会打印到串口并加上 recv : 回发。由于 TCP
不保留消息边界,正式应用应自行定义定长、分隔符或长度字段协议。
连接生命周期#
例程把包含 end 的数据作为当前连接的结束标记,关闭客户端 Socket 后返回
accept() 等待下一个连接:
if b"end" in h:
client_stream.close()
break
read() 返回字节数据,因此结束标记也应使用 b"end"。若当前脚本仍使用字符串
"end",请先按上面的写法修正,否则严格区分字符串和字节的运行时会报告类型
错误。计数超过 10 后,服务关闭监听 Socket 并退出。这个例程按客户端逐个处理
连接;需要持续并发服务时,应增加连接状态管理和多客户端调度。
运行与验证#
运行脚本并记下串口输出的 IP 和
8080端口。在电脑 TCP 客户端中连接该地址。
确认电脑收到欢迎消息,然后发送文本。
串口应打印收到的字节,电脑端应收到带
recv :前缀的回显。发送
end结束当前连接。
连接失败时检查开发板 IP 是否变化、两端是否处于可达网络,以及 TCP 8080 是否被
防火墙拦截。
