px普贤教程PuXian
普贤教程 › 生态包

网络与协议

网络这一组包不做「框架」,只做协议原语: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,不做半开扫描、不做并发批扫。

邮件三件套 + 发送

包协议典型用途
smtpSMTP 客户端发信(smtp_send)
imapIMAP4rev1收信、找未读、按文件夹取
pop3POP3简单拉取全部
mailparseRFC 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() 判一下,别假设一定成功。