普贤教程 › 生态包
网络与协议
网络这一组包不做「框架」,只做协议原语:DNS 查询、端口探测、IP/CIDR 计算、FTP/MQTT/SMTP/IMAP/POP3 客户端、URL 百分号编码、边缘设备 IO。全部纯 PuXian,编译后不带任何动态库。
IP 与 CIDR
px
import ipaddr print(ipv4_parse("192.168.1.10")) # Ok(3232235786) ← 32 位整数 print(ipv4_in_cidr("192.168.1.10", "192.168.1.0/24")) # true print(cidr_parse("10.0.0.0/8")) print(ipv4_cidr_network("192.168.1.10/24")) # 192.168.1.0 print(ipv4_to_str(3232235786)) # 192.168.1.10
白名单判断只用这一个函数
ipv4_in_cidr(ip, cidr)。别自己拿字符串 starts_with 比前缀——10.0.0.1 与 10.0.0.10 会误判。DNS 查询
px
import dns var r = dns_query("223.5.5.5", "px.dzty.club", "A") # (server, name, type) print(r)
自实现 UDP DNS 报文(构造 + 解析),支持 A / AAAA / CNAME / NS / MX / TXT / PTR。注意两点:① 只查指定 server,不走系统 resolver;② 多线路解析的域名,不同 server 的答案不一样——判断「这台域名指向哪」时至少要问两个不同网络的 DNS,否则结论不完整。
端口探测
px
import netprobe print(np_check("127.0.0.1", 3306, 1000)) # 连得上否,返回 dict print(np_banner("127.0.0.1", 22, 2000)) # banner(SSH/FTP/SMTP 第一行)
做健康检查够用;它不是 nmap,不做半开扫描、不做并发批扫。
邮件三件套 + 发送
| 包 | 协议 | 典型用途 |
|---|---|---|
smtp | SMTP 客户端 | 发信(smtp_send) |
imap | IMAP4rev1 | 收信、找未读、按文件夹取 |
pop3 | POP3 | 简单拉取全部 |
mailparse | RFC 5322 子集 | 解析头部、multipart、附件、编码 |
px
import smtp var msg = "From: noreply@example.com\r\n" + "To: a@b.com\r\n" + "Subject: 验证码\r\n" + "Content-Type: text/plain; charset=utf-8\r\n\r\n" + "你的验证码是 123456" var r = smtp_send("smtp.example.com", 465, "noreply@example.com", ["a@b.com"], msg, {"tls": true, "user": "noreply@example.com", "pass": env("SMTP_PASS")}) print(r) # Ok(true) / Err(...)
发信一定要异步一次 SMTP 往返 0.3–3 秒。放在请求线程里,20 个用户同时点「获取验证码」就把 worker 占满。正确做法:请求里只落库(
INSERT mail_queue)+ 立即返回,常驻进程轮询发信。patterns 页的 sched 就是干这个的。MQTT 与 FTP
px
import mqtt var c = mqtt_connect("127.0.0.1", 1883, "px-client") mqtt_publish(c, "sensors/temp", "26.5") mqtt_subscribe(c, "sensors/#")
MQTT 3.1.1 子集:connect / publish / subscribe / ping。FTP 是 RFC 959 子集:登录、PASV、LIST、RETR、STOR。两者都是「能跑通」级别,不是全套实现——用前先看包页的接口表。
URL 编码与 IDN
px
import percent print(percent_encode("你好 world")) # %E4%BD%A0%E5%A5%BD%20world print(percent_decode("%E4%BD%A0")) # 你 import punycode print(pd_encode("中文.cn")) # xn--fiq228c.cn
拼 query、做回调地址一律用 percent_encode,别手写 replace——空格、+、中文三处都会出错。
边缘设备 IO
edge(std 级别)直接操作 GPIO V2 line / I2C / 串口 / PWM sysfs:open/read/write/ioctl 是内建,edge 负责把内核结构体布局封好。它属于「在板子上跑」的能力,云主机上装了也没设备节点;失败返回 -1 / false + os_errno(),不杀进程。
这一组包共同的坑
- 超时永远显式给:不传 timeout 就走默认值,网络挂住时请求会卡在那里。
{"timeout_ms": 2000}是常用值。 - 连接是 fd,不是线程安全:多协程共享一条连接会串包。
- 明文协议不要过公网:SMTP/IMAP/POP3/FTP 的明文端口在内网或回环用,出公网一律 TLS。
- 失败返回 Err,不是异常:
is_err()判一下,别假设一定成功。