Trae的十二时辰-驱动GLM5.2用AI重构Python版飞鸽传书(iptux)

本文记录了使用 AI 开发环境与大语言模型,在 24 小时内完成 Python 版 iptux(飞鸽传书兼容)复刻的全过程。

本项目已开源,仓库地址:https://gitcode.com/colorEagleStdio/pyqtux.git


第一章:前言与项目背景

1.1 项目缘起

飞鸽传书(IPMsg)是一款经典的局域网即时通讯软件,诞生于 Windows 平台,以其高效的文件传输能力和无需服务器的特点,成为企业和校园局域网中不可或缺的工具。iptux 是飞鸽传书协议在 Linux 平台上的开源实现,继承了飞鸽传书的核心功能,同时扩展了群组、共享文件等特性。

然而,随着 Windows 平台上飞鸽传书的逐步停止更新,以及 Linux 发行版对 iptux 的支持参差不齐,用户面临着跨平台互操作的难题。本项目旨在利用现代 Python 技术栈,在 Windows 平台上复刻 iptux 的完整功能,实现与原版 iptux 和飞鸽传书的完全协议兼容。

1.2 技术选型与工具链

开发环境

  • 主开发机:Windows 10
  • 协议对照机:Linux 开发机,运行原版 iptux 0.8.3

技术栈

  • 语言:Python 3.10+(Windows)/ Python 3.11(Linux)
  • GUI框架:PyQt6(Windows)/ PyQt5(Linux)
  • 网络通信:asyncio 异步网络编程
  • 测试框架:pytest

AI 工具链

  • IDE:Trae AI 辅助开发环境 Solo模式
  • 模型:GLM5.2大语言模型(代码生成、调试、文档编写)
  • 测试验证:Wireshark / tcpdump 抓包分析

Shell 工作流

项目采用脚本化策略:

  • 复杂命令(SSH、rsync、管道等)通过写 .sh 文件执行
  • 这种方式避免了 Shell 兼容性问题,确保跨平台脚本一致性

1.3 目标与约束

核心目标

  1. 协议完全兼容:与 iptux 0.8.3、飞鸽传书字节级协议兼容
  2. 功能完整复刻:实现好友发现、消息收发、文件传输、头像签名等所有核心功能
  3. 跨平台运行:支持 Windows 和 Linux
  4. 独立控制台版本:核心层无 UI 依赖,可独立运行控制台版

硬约束

  1. 核心层零 PyQt 依赖pyqtux/core/ 目录必须纯 Python,可在无 GUI 环境运行
  2. 协议字节级兼容性:分隔符、命令字、报文格式必须与原版完全一致
  3. 默认端口 2425:与原版 iptux/飞鸽传书保持一致
  4. 编码兼容:支持 GB18030、GBK、Big5 到 UTF-8 的自动转换

开发周期

项目计划在 24 小时内完成,分为 6 个阶段、24 个任务,每个阶段都有明确的可验证产出。


第二章:协议分析与架构设计

2.1 IPMsg/iptux 协议深度剖析

协议基础

IPMsg 协议是一种基于 UDP/TCP 的局域网即时通讯协议,采用明文传输,具有简单高效的特点。核心报文格式如下:

复制代码
IPMsg 报文:version:packet_no:sender:host:command:additional\0extras\0...
  • 前 5 个字段以冒号 : 分隔
  • iptux 扩展段以 \0 分隔,前 3 段固定为 group\0icon\0encoding
  • 文件名中的冒号需要转义为 ::

关键命令字

命令 用途
BR_ENTRY 0x101 上线广播(带 ABSENCEOPT)
ANSENTRY 0x103 应答上线(带 ABSENCEOPT)
BR_EXIT 0x2 下线通知
BR_ABSENCE 0x4 信息变更
SENDMSG 0x20 发送消息
RECVMSG 0x21 消息回执
IPTUX_SENDICON 0xFE 发送头像(UDP)
IPTUX_SEND_SIGN 0xFC 发送签名(UDP)
IPTUX_SENDSUBLAYER 0xFD 底层数据(TCP,照片/图片)

协议扩展

iptux 在 IPMsg 基础上扩展了以下功能:

  1. 扩展字段:BR_ENTRY/ANSENTRY 报文中携带 group、icon、encoding 信息
  2. 头像传输:UDP SENDICON + SHA256 去重
  3. 个性签名:UDP SEND_SIGN
  4. 形象照片:TCP SUBLAYER + PHOTOPICOPT
  5. 内嵌图片消息:TCP SUBLAYER + MSGPICOPT

文件传输流程

文件传输是协议中最复杂的部分,分为三个阶段:

  1. UDP 文件信息通知:发送方通过 SENDMSG + FILEATTACHOPT 发送文件列表
  2. TCP 连接建立:接收方主动连接发送方,请求文件数据
  3. 数据传输:发送方按 8KB 分块发送文件内容

目录传输还涉及虚拟文件系统(AnalogFS)的模拟:

  • 发送目录头(大小为 0,DIR_ATTR 属性)
  • 递归发送子目录和文件
  • 发送 RETPARENT 标记返回父目录

2.2 架构设计原则

分层架构

项目采用清晰的三层架构:

复制代码
┌─────────────────────────────────────────────┐
│              UI 层(PyQt6)                   │
│  MainWindow / DialogPeer / DialogGroup      │
│  TransWindow / ShareFile / DataSettings     │
├─────────────────────────────────────────────┤
│            事件桥接层(CoreBridge)           │
│  Qt 信号 ↔ 核心层事件的双向转换               │
├─────────────────────────────────────────────┤
│              核心层(纯 Python)               │
│  CoreThread / CommandBuilder / Packet       │
│  UdpDataHandler / TcpDataHandler            │
│  SendFile / RecvFile / AnalogFS             │
└─────────────────────────────────────────────┘

设计原则

  1. 核心层零 UI 依赖pyqtux/core/ 目录完全独立,可运行控制台版
  2. 事件驱动架构:核心层通过事件系统与 UI 解耦
  3. 协议字节级兼容:所有报文构造和解析严格遵循原版格式
  4. 测试驱动开发:每个功能模块都有完整的单元测试
  5. 跨平台兼容:配置路径、网络接口等采用平台自适应

模块职责

模块 职责 关键文件
协议常量 命令字、选项、文件属性定义 ipmsg.py
报文处理 IpmsgPacket 解析与构造 packet.py
编码转换 GB18030/GBK/Big5 → UTF-8 encode.py
数据模型 PalInfo、FileInfo 等 models.py
命令构造 所有协议命令的构造方法 command.py
UDP 处理 UDP 报文分派与处理 udp_data.py
TCP 处理 TCP 连接分派(文件/照片) tcp_data.py
文件传输 SendFile、RecvFile、AnalogFS send_file.py, recv_file.py, analog_fs.py
核心服务 asyncio 事件循环、好友管理 core_thread.py

2.3 开发计划与里程碑

六阶段开发计划

阶段 主题 任务数 关键产出 测试数
1 项目骨架与协议常量 4 可导入的空项目骨架 224
2 核心层:报文与数据模型 5 报文解析/构造单测通过 402
3 核心层:网络服务与控制台版 5 控制台全功能版本 734
4 UI 层:主窗口与好友列表 4 可见好友列表的 GUI 870
5 UI 层:聊天与文件传输 4 完整聊天+文件传输 GUI 1033
6 UI 层:辅助功能与打磨 2 发布就绪的完整应用 1118

里程碑

  1. 阶段 3 结束:拥有可用的控制台版本,可与原版 iptux 互操作
  2. 阶段 5 结束:完整 GUI 功能,所有核心测试通过
  3. 阶段 6 结束:发布就绪,三端互操作矩阵全部验证通过

协同策略

项目采用主开发机 + 协议对照机的双机验证模式:

  1. 跨平台单测:推送代码到对照机,执行 pytest 验证核心层兼容性
  2. 协议对照:对照机上运行原版 iptux 0.8.3,本机 pyqtux 与之互操作
  3. 双实例测试:对照机上部署 pyqtux 控制台版,进行真实双机通信

所有依赖外部环境的测试用标记,离线时自动跳过。


第三章:核心层开发(阶段1-3)

3.1 阶段1:项目骨架与协议常量

阶段 1 的目标是搭建项目结构,定义所有协议常量,为后续开发奠定基础。

任务 1.1:创建项目骨架

创建了完整的项目结构:

复制代码
pyqtux/
├── main.py                      # 程序入口
├── pyproject.toml               # 项目元数据与依赖
├── requirements.txt             # 依赖清单
├── pyqtux/
│   ├── __init__.py
│   ├── core/                    # 核心层
│   ├── ui/                      # UI 层
│   └── utils/                   # 工具
└── tests/
    ├── conftest.py
    └── integration/             # 集成测试

任务 1.2:协议常量定义

ipmsg.py 中定义了所有协议常量:

  • CommandMode 枚举:所有命令模式(BR_ENTRY、SENDMSG、RECVMSG 等)
  • CommandOpt IntFlag:所有命令选项(SENDCHECKOPT、FILEATTACHOPT 等)
  • FileAttr 枚举:文件类型属性(REG_ATTR、DIR_ATTR、RETPARENT_ATTR)
  • 辅助函数:get_mode()get_opt()
  • 常量:IPTUX_VERSION=1IPMSG_PORT=2425MAX_UDPLEN=8192

任务 1.3:数据模型定义

models.py 中定义了核心数据结构:

  • PalKey:好友唯一标识(ipv4 + port)
  • PalInfo:好友信息(昵称、群组、头像、签名、编码等)
  • FileInfo:文件信息(文件ID、路径、大小、时间、属性)
  • NetSegment:网段管理(count()、nth_ip()、contain_ip())

任务 1.4:事件类型与配置管理

  • events.py:定义了 14 种事件类型(PalOnlineEvent、NewMessageEvent、SendFileFinishedEvent 等)
  • config.py
    • IptuxConfig:JSON 配置读写,与原版兼容
    • ProgramData:运行时数据管理
    • 跨平台路径处理(Windows %APPDATA% / Linux ~/.config)

阶段 1 成果:224 个单元测试全部通过,跨平台验证成功。

3.2 阶段2:报文与数据模型

阶段 2 的核心目标是实现报文构造/解析、编码转换和文件信息编解码。

任务 2.1:报文构造与解析

packet.py 实现了 IpmsgPacket dataclass:

  • to_bytes(encode):序列化报文字节流
  • from_bytes(data, default_encode):反序列化解析报文
  • 处理 \0 分隔的 iptux 扩展字段
  • 处理冒号分隔的字段解析

关键发现:协议文档附录 B.1 存在错误,BR_ENTRY 实际值为 0x101 (257),而非文档所写的 0x105 (261)。这一发现通过抓取真实 iptux 0.8.3 报文得到验证。

任务 2.2:编码转换工具

encode.py 实现了中文编码转换:

  • convert_encode(data, to_encode, from_encode):字节流编码转换
  • validate_utf8(data, codeset):验证并转换为 UTF-8
  • make_valid_utf8(data):强制转为有效 UTF-8

支持 GB18030、GBK、Big5 等常见中文编码,处理了 Big5 字节在 GB18030 中也能解码但结果错误的边界情况。

任务 2.3:文件信息编解码

packet.py 中集成了文件信息编解码:

  • encode_file_info(file_info):编码为 IPMsg 格式
  • decode_file_infos(data):解码文件信息列表

文件信息格式:fileid:filename:filesize:filectime:fileattr:\a

关键发现 :文件名中的冒号 : 需要转义为 ::,否则会导致协议解析错误。

任务 2.4:网络工具函数

network.py 实现了跨平台网络工具:

  • get_broadcast_addresses():跨平台获取广播地址(Windows 使用 psutil,Linux 使用 ioctl)
  • IP 地址转换和广播地址计算

任务 2.5:格式化工具

format.py 实现了数据格式化:

  • numeric_to_size(n):字节大小格式化(B/KiB/MiB/GiB/TiB)
  • numeric_to_rate(n):速率格式化(B/s/K/s/M/s/G/s)
  • numeric_to_time(n):时间长度格式化(HH:MM:SS)

阶段 2 成果:402 个单元测试通过,真实报文解析验证成功,协议文档勘误确认。

3.3 阶段3:网络服务与控制台版本

阶段 3 是项目的关键里程碑,交付可用的控制台版本。

任务 3.1:命令构造器

command.py 实现了 CommandBuilder 类,包含所有协议命令的构造方法:

  • broadcast(port):广播上线
  • send_message(pal, msg):发送消息(带重试机制)
  • send_reply(pal, packet_no):消息回执
  • send_file_info(pal, opt, extra):发送文件信息
  • send_my_icon(pal, icon_data):发送头像
  • send_my_sign(pal):发送签名
  • send_sublayer(pal, opt, path):发送底层数据(照片/图片)

包号自增管理通过 property 实现,确保每个命令有唯一的 packet_no。

任务 3.2:UDP 数据处理

udp_data.py 实现了 UdpDataHandler 类,对应原版 UdpDataService

  • 命令分派:根据 get_mode(command) 调用对应处理函数
  • _on_entry:好友上线处理(创建/更新 PalInfo,回应 ANSENTRY)
  • _on_sendmsg:消息接收(回执、去重、文件附件提取)
  • _on_recvmsg:回执处理
  • _on_send_icon:头像接收
  • _on_send_sign:签名接收

任务 3.3:TCP 数据处理与文件传输

这是阶段 3 最复杂的部分,涉及多个模块:

  • tcp_data.py:TCP 连接分派(GETFILEDATA / GETDIRFILES / SUBLAYER)
  • send_file.py:文件信息发送、文件数据发送(常规文件 + 目录递归)
  • recv_file.py:文件信息接收、文件数据接收
  • analog_fs.py:虚拟文件系统(chdir/mkdir/open,支持目录递归传输)
  • trans_task.py:传输任务管理

任务 3.4:核心服务(CoreThread)

core_thread.py 是核心服务的中枢,基于 asyncio 实现:

  • start():绑定 UDP/TCP 2425 端口、启动接收、广播上线
  • stop():通知下线、关闭 socket
  • UDP 接收循环(asyncio DatagramProtocol)
  • TCP 接收循环(asyncio Server + Protocol)
  • 好友列表管理(get_palattach_paldel_palupdate_pal
  • 传输任务管理(register_trans_taskterminate_trans_task
  • 事件分发(emit_eventon_event

设计要点

  • 事件循环在独立线程运行,UI/控制台主线程不被阻塞
  • udp_send 通过 call_soon_threadsafe 保证线程安全
  • 好友列表用 dict[PalKey, PalInfo] 索引,O(1) 查找

任务 3.5:控制台版本

console.py 实现了无 GUI 的控制台交互界面:

  • list:列出在线好友
  • send <ip> <msg>:发送消息
  • file <ip> <path>:发送文件
  • share / share add <path>:管理共享文件
  • detect <ip>:探测好友
  • exit:退出

实时显示收到的事件(上线/下线/消息/文件请求)。

阶段 3 成果

  1. 控制台全功能版本交付:可与原版 iptux 互操作
  2. 互操作三连测通过
    • 发现 ✅:互相出现在好友列表
    • 消息 ✅:中文消息正确送达
    • 文件 ✅:文件完整传输
  3. 734 个单元测试 + 7 个集成测试通过

后续修复 :阶段 3 完成后发现 send_message 的 RECVMSG 回执识别 bug,根因为 packet_no 自增 property 被调用两次,导致 pal.rpacketn 与实际 packet_no 不一致。修复后双向消息回执均能正确识别。


第四章:UI层开发(阶段4-5)

4.1 阶段4:主窗口与好友列表

阶段 4 的目标是实现 GUI 主框架,显示好友列表,响应上线/下线事件。

任务 4.1:UI 框架与事件桥接

application.py 实现了 UI 层的核心框架:

  • Application 类:管理 QApplication、CoreThreadWrapper、各窗口
  • CoreBridge(QObject):定义所有 UI 信号(pal_online、pal_update、new_message 等),共 14 个信号
  • CoreThreadWrapper(QThread):在独立线程运行 asyncio loop,转发核心层事件到 Qt 信号

main.py 是程序入口,创建 Application 并运行。

设计要点

  • 核心层事件通过 CoreBridge 转换为 Qt 信号,实现 UI 与核心层的解耦
  • asyncio 事件循环在独立线程运行,不阻塞 Qt 主线程

任务 4.2:主窗口与好友树

main_window.py 实现了主窗口:

  • 工具栏:探测好友、共享文件、传输管理、日志、关于、设置
  • 好友树:按群组/网段分组显示好友(头像 + 昵称 + IP + 群组)
  • 信息面板:显示选中好友的详细信息
  • 状态栏:显示在线好友数、当前状态

models.py 实现了好友树模型:

  • PalTreeModel(QAbstractItemModel):好友树数据模型
  • GroupNodePalNode:树节点类型
  • 支持按昵称/IP 排序
  • 右键菜单:发送消息、请求共享、修改信息、删除好友

任务 4.3:资源与图标

resources.py 实现了图标缓存与访问:

  • 使用 importlib.resources 加载包内图标资源
  • 32 个内置头像图标(icon-blowfish、icon-dog、icon-penguin 等)
  • 界面图标(iptux-icon、tip-send、tip-recv 等)

资源文件位于 pyqtux/resources/icons/ 目录,分为 app、avatar、menu、tip 四类。

任务 4.4:系统托盘与基础对话框

阶段 4 成果:8 个源文件 + 4 个测试文件 + 资源目录,136 个 UI 单测全部通过。

4.2 阶段5:聊天与文件传输

阶段 5 的目标是实现完整聊天与文件传输 GUI。

任务 5.1:聊天窗口基类与单人聊天

dialog_base.py 实现了聊天窗口基类 DialogBase

  • 历史记录区:使用 QTextBrowser(支持 HTML 和内嵌图片)
  • 输入区:QTextEdit(支持拖拽文件、粘贴图片)
  • 文件附件区:QTreeView(待发送文件列表)
  • 工具栏:发送/附件/文件夹/图片按钮
  • 拖拽支持:拖入文件自动添加附件

dialog_peer.py 实现了单人聊天窗口:

  • 标题显示好友信息
  • 接收文件区:待接收/已接收文件列表,接受/拒绝按钮
  • 发送消息:调用 core.send_message
  • 发送文件:构造文件信息,发送 SENDMSG + FILEATTACHOPT
  • 接收图片消息:TCP SUBLAYER + MSGPICOPT

关键修复

  • 初始使用 QPlainTextEdit 只支持纯文本,无法显示图片
  • 改用 QTextBrowser 支持 HTML 和内嵌图片
  • 使用 QTextDocument.addResource() 添加图片资源,第二参数必须是 QUrl 类型

任务 5.2:群组聊天窗口

dialog_group.py 实现了群组聊天窗口:

  • 成员列表区:MemberTreeWidget(昵称/IP/群组三列)
  • 群发消息:遍历群组成员调用 send_group_msg
  • 广播消息:IPTUX_SENDMSG + BROADCASTOPT
  • 网段消息:IPTUX_SENDMSG + SEGMENTOPT
  • 分组消息:IPTUX_SENDMSG + GROUPOPT

任务 5.3:文件传输窗口

trans_window.py 实现了文件传输管理窗口:

  • TransWindow(QMainWindow,单例)
  • TransTaskModel(QAbstractTableModel):传输任务表格模型
  • 列:状态、任务、对方、IP、文件名、进度、完成/总大小、耗时、剩余、速率
  • 工具栏:清除已完成、终止任务、刷新
  • QTimer 500ms 自动刷新 + bridge.trans_tasks_changed 信号触发重载

share_file.py 实现了共享文件管理对话框:

  • 添加/删除共享文件(fileid 从 1 起 < MAX_SHAREDFILE=10000)
  • 持久化到 ProgramData._shared_file_infos

任务 5.4:好友信息修改与日志

  • revise_pal.py:修改好友信息对话框(昵称、群组、编码、头像、兼容性)
  • log_window.py:日志查看窗口(系统日志 + 按好友聊天日志)
  • logger.py:日志系统

阶段 5 成果 :7 个源文件 + 6 个测试文件,180 个 UI 单测全部通过,全量回归 1033 passed

4.3 阶段6:辅助功能与打磨

阶段 6 的目标是完善细节,达到发布就绪状态。

任务 6.1:头像/签名/形象照片完整支持

实现了头像接收与显示(UDP SENDICON + SHA256 缓存去重)、个性签名显示(UDP SEND_SIGN)、形象照片接收与显示(TCP SUBLAYER PHOTOPICOPT)。

关键修复_on_entry/_on_ansentry 未调用 send_feature_data,导致好友上线时不主动发送头像/签名。

任务 6.2:最终集成测试与打包

完成了完整功能集成测试和与原版 iptux 的互操作测试。

额外优化

  1. 消息换行修复 :QTextBrowser 的 insertHtml 对连续块级元素不会自动创建段落分隔符,导致消息全挤一行。改用 cursor.insertBlock() + cursor.insertText() 显式段落分隔。

  2. 宽屏布局重构:会话窗口从垂直布局改为水平+垂直混合布局:

    • 水平 QSplitter 作为顶层(左大区 + 右侧边栏)
    • 左大区保留垂直 QSplitter(聊天历史 + 输入区)
    • 右侧侧边栏放附件树 + 操作按钮
    • 默认尺寸 960×540(16:9)

阶段 6 成果 :全量回归 1118 passed,三端互操作矩阵全部验证通过。


第五章:协议兼容性与互操作测试

5.1 三端互操作矩阵

项目采用三端验证策略:本机 pyqtux (Windows)、Linux pyqtux、Linux 原版 iptux 0.8.3。最终验收结果如下:

发送方 \ 接收方 本机 pyqtux (Win) Linux pyqtux Linux 原版 iptux 0.8.3
本机 pyqtux --- ✅ 发现+消息+文件 ✅ 发现+消息+文件
Linux pyqtux ✅ 发现+消息+文件 --- 待测(需 GUI 手动)
Linux 原版 iptux ✅ 头像+签名(自动 FeatureData) 待测 ---

验证记录

2026-07-17:阶段 3 验收门通过

  • 双向互操作三连测全部成功:
    • 发现 ✅:互相出现在好友列表
    • 消息 ✅:中文消息正确送达
    • 文件 ✅:文件完整传输

2026-07-18:双向互操作验证通过

  • 双向消息+文件已通过
  • 反向测试:发现 ✅、消息 ✅(RECVMSG 回执双向识别)、文件 ✅(UTF-8 中文内容完整)

2026-07-18:头像/签名互通验证通过

  • 头像 + 签名字节级互通
  • SHA256 缓存 + sign 正确处理

5.2 真实报文对照验证

抓包验证流程

  1. 在对照机上启动原版 iptux 0.8.3
  2. 使用 tcpdump -i any port 2425 -w /tmp/iptux.pcap 抓取报文
  3. 将 pcap 文件拉回本机
  4. 使用解析工具解析并与 IpmsgPacket.from_bytes 结果对比

BR_ENTRY 报文对照

真实抓包(iptux 0.8.3)

复制代码
version="1_iptux 0.8.3"
packet_no=1784295655
sender="testuser"
host="devbox"
command=0x101 (BR_ENTRY + ABSENCEOPT)
additional="TestUser"
extras=["group", "icon-qq.png", "utf-8"]

pyqtux 解析结果:完全一致,字段值无偏差。

RECVMSG 回执对照

对比 iptux 0.8.3 和 pyqtux 的 RECVMSG 回执报文:

字段 iptux 0.8.3 pyqtux
command 0x121 0x121
mode 0x21 0x21
opt 0x100 0x100
additional "1784295655" "1784295655"
分隔符 : :
终止符 \0 \0

结论:RECVMSG 回执报文字节级完全一致,协议兼容性得到验证。

文件传输协议对照

通过 Wireshark 分析抓包中的 TCP 目录数据流,发现并修复了以下协议差异:

  1. UDP 文件信息末尾冒号 :iptux 0.8.3 格式为 fileid:filename:filesize:filectime:fileattr:\x07,早期实现多一个冒号导致解析异常
  2. TCP 文件头 filesize 补零 :iptux 0.8.3 使用 9 位零填充十六进制 %09x,早期使用可变长度 %x
  3. 子目录头重复发送:早期在发送目录时重复发送子目录头,导致 iptux 段错误

5.3 协议文档勘误

附录 B.1:BR_ENTRY 命令值

文档值 :0x105 (261)

实际值:0x101 (257)

通过抓取真实 iptux 0.8.3 BR_ENTRY 报文证实,BR_ENTRY = 0x1(上线命令)+ 0x100(ABSENCEOPT)= 0x101。

附录 B.3:SENDMSG + FILEATTACHOPT

文档值 :0x202020 (2103296)

实际值:0x200020 (2097184)

正确计算:SENDMSG = 0x20 + FILEATTACHOPT = 0x200000 = 0x200020。

重要发现

  1. iptux 扩展字段顺序[group, icon, encoding]is_iptux_compatible 需要 >=3 个 extras
  2. 版本字符串区分
    • iptux:1_iptux 0.8.3
    • 飞鸽传书:1_lbt6_0#...
  3. 编码自动检测from_bytes 先尝试 UTF-8,失败则回退到 default_encode 参数
  4. 文件时间戳处理:Windows 时间戳可能为负数,需转换为无符号 32 位整数

飞鸽传书兼容性

飞鸽传书(Feige)报文格式与 iptux 略有差异,主要体现在:

  • 版本字符串格式不同(1_lbt6_0#... vs 1_iptux ...
  • 扩展字段可能缺失或格式不同

pyqtux 通过 compat=False 标记区分飞鸽传书报文,确保协议兼容。

5.4 互操作测试脚本

项目提供了完整的互操作测试脚本和集成测试框架,所有依赖外部环境的测试用标记,离线时自动跳过。


第六章:技术难点与解决方案

6.1 编码兼容问题

中文编码歧义

问题描述:Big5 编码的"你好"字节也是合法的 GB18030 编码,但解码结果完全不同。这导致自动检测编码时可能产生错误的解码结果。

解决方案

  • make_valid_utf8 中优先尝试 UTF-8
  • 如果 UTF-8 解码失败,按优先级尝试 GB18030 → GBK → Big5
  • 每个编码尝试后验证结果是否合理(通过字符范围检查)
  • 所有编码都失败时使用 errors="replace" 降级处理

跨平台编码转换

问题描述:不同平台默认编码不同,Windows 使用 GBK,Linux 使用 UTF-8。

解决方案

  • 核心层统一使用 UTF-8 内部表示
  • 协议层面支持多种编码(GB18030、GBK、Big5)
  • from_bytes 自动检测编码并转换为 UTF-8
  • to_bytes 根据对方的编码设置转换为对应编码

6.2 文件传输协议细节

UDP 文件信息格式

问题描述 :iptux 0.8.3 的 UDP 文件信息格式为 fileid:filename:filesize:filectime:fileattr:\x07,早期实现多了一个末尾冒号,导致 iptux 解析异常。

解决方案

  • 修改 encode_file_info 函数,移除末尾多余的冒号
  • 添加回归测试确保格式正确

TCP 文件头 filesize 补零

问题描述 :iptux 0.8.3 使用 9 位零填充十六进制 %09x(如 0000007db),早期使用可变长度 %x(如 7db)。

解决方案

  • 修改 _send_dir_recursive 中的文件头构造逻辑
  • 使用 f"{filesize:09x}" 确保 9 位零填充
  • 更新受影响的测试断言

子目录头重复发送

问题描述 :早期在发送目录时,父循环会预先发送目录头,而 _send_dir_recursive 内部也会发送,导致重复发送子目录头,iptux 接收到重复目录头后段错误。

解决方案

  • 修改 send_file.py,移除父循环中预先发送目录头的逻辑
  • 确保目录头仅由递归函数发送
  • 添加回归测试 test_send_nested_dir_no_duplicate_subdir_header

目录大小计算错误

问题描述 :使用 os.path.getsize() 计算目录大小会返回目录元数据大小(通常 4096 字节),而非目录内容的真实大小。

解决方案

  • 使用 AnalogFS().ftwsize(filepath) 递归计算目录总大小
  • 在多个模块(send_file、dialog_base、share_file、console)中统一使用此方法
  • 添加测试验证目录大小计算正确性

文件时间戳处理

问题描述:Windows 上文件时间戳可能为负数(如 1970 年前的文件),直接发送会导致协议异常。

解决方案

  • 转换为无符号 32 位整数:mtime & 0xFFFFFFFF
  • 确保时间戳在协议允许的范围内

传输失败时的目录层级混乱

问题描述 :文件发送失败时直接 return,导致 afs.chdir("..") 未执行,造成目录层级混乱。

解决方案

  • send_file.py 中添加 afs.chdir("..")self._terminated = True 后再返回
  • 使用 try/finally 确保目录回退逻辑一定执行

6.3 Qt 与 asyncio 集成

事件循环线程安全

问题描述:Qt 主线程和 asyncio 事件循环在不同线程运行,直接调用会导致线程安全问题。

解决方案

  • 使用 CoreThreadWrapper 将 asyncio 事件循环封装在 QThread 中
  • 通过 Qt 信号槽机制跨线程通信
  • udp_send 使用 call_soon_threadsafe 保证线程安全

QTextBrowser 消息换行

问题描述insertHtml("<div>/<p>...") 对连续块级元素不会自动创建段落分隔符,导致消息全挤一行。

解决方案

  • 改用 cursor.insertBlock() + cursor.insertText() 显式段落分隔
  • insertText 处理纯文本可天然防 HTML 注入,无需 html.escape

QTextDocument.addResource 参数类型

问题描述 :PyQt6 中 QTextDocument.addResource() 的第二参数必须是 QUrl 类型,传入字符串会导致图片无法显示。

解决方案

  • 将图片路径转换为 QUrl:QUrl.fromLocalFile(path)
  • 添加类型检查确保参数正确

好友列表时序问题

问题描述:MainWindow 创建前核心层可能已发出好友上线事件,但此时没有信号接收方,导致好友列表看不到已在线的好友。

解决方案

  • main_window.py 中新增 _sync_existing_pals 方法
  • MainWindow 创建后主动从核心层同步现有好友
  • 调整 application.py 中的启动顺序

QFontComboBox.setCurrentFont 类型错误

问题描述ProgramData.font 存储的是字体 family 名字符串,但 QFontComboBox.setCurrentFont 需要 QFont 对象。

解决方案

  • data_settings.py 中添加 QFont 导入
  • 修改调用为 setCurrentFont(QFont(font_string))

6.4 跨平台部署

Shell 环境差异

问题描述:不同 Shell 环境语法差异,不支持某些 bash 特性。

解决方案

  • 采用脚本化策略:复杂命令写 .sh 文件再执行
  • 使用无 BOM 的 .sh 文件
  • 避免内联执行形式,一律写文件再执行

抓包链路层差异

问题描述 :Linux 上 tcpdump -i any 使用 Linux SLL2(linktype 276,header 20 字节),而非 Ethernet(14 字节)。

解决方案

  • 在解析工具中处理不同链路层类型
  • 确保 Wireshark 能正确解析抓包文件

6.5 协议层疑难问题

RECVMSG 回执识别失败

问题描述send_message 报 TimeoutError,但实际已回复 RECVMSG 回执。

根因分析packet_no 自增 property 被调用两次(一次在 send_message,一次在 _make_packet),导致 pal.rpacketn(N) ≠ 实际 packet_no(N+1)

解决方案

  • 修改 send_message 逻辑,先调用 _make_packet,再提取 pkt.packet_no,最后设置 pal.rpacketn
  • 添加回归测试确保回执识别正确

iptux 0.8.3 不发送 RECVMSG

问题描述 :iptux 0.8.3 不针对 SENDMSG+SENDCHECKOPT 主动发 RECVMSG 回执。

解决方案

  • pyqtux 兼容此行为:消息送达即视为成功
  • 记录此行为为已知限制,不视为 bug

形象照片协议支持

问题描述:形象照片需要通过 TCP SUBLAYER + PHOTOPICOPT 发送,协议较为复杂。

解决方案

  • tcp_data.py 中增强 SUBLAYER 处理逻辑
  • core_thread.py 中添加 send_msg_pic() 方法
  • 支持内嵌图片消息(MSGPICOPT)和形象照片(PHOTOPICOPT)

6.6 UI 布局优化

宽屏布局重构

问题描述:原布局为垂直布局,在 16:9 宽屏显示器上显示效果不佳。

解决方案

  • 使用水平 QSplitter 作为顶层布局容器
  • 左大区保留垂直 QSplitter(聊天历史 + 输入区)
  • 右侧侧边栏放附件树 + 操作按钮(清空/删除/发送)
  • 工具栏按钮(附件/文件夹/图片)留在输入区上方
  • 默认尺寸改为 960×540(16:9)

子类兼容性

问题描述 :DialogPeer 和 DialogGroup 通过 self._splitter.insertWidget(0, ...) 插入额外区域,布局重构可能破坏此功能。

解决方案

  • 保留 self._splitter 作为左大区的垂直布局
  • 子类的插入逻辑仍然生效,无需修改
  • 添加回归测试验证子类兼容性

第七章:经验总结与未来展望

7.1 AI 驱动开发的体会

AI 辅助的优势

  1. 快速原型开发:大语言模型能够根据需求描述快速生成完整的代码框架和实现,大大缩短了开发周期
  2. 协议解析加速:AI 能够快速理解复杂的协议文档,并生成对应的解析代码
  3. 调试效率提升:遇到问题时,AI 能够分析错误信息,提供可能的解决方案
  4. 文档自动化:AI 能够自动生成测试用例、注释和文档,确保代码质量
  5. 跨平台支持:AI 能够处理不同平台的差异,提供跨平台兼容的解决方案

AI 辅助的挑战

  1. 协议细节偏差:AI 生成的代码可能与原版协议存在细微差异,需要通过真实报文对照验证
  2. 环境差异:AI 不了解本地开发环境的特殊性,需要手动调整
  3. 复杂逻辑处理:对于复杂的递归逻辑(如目录传输),AI 可能需要多次迭代才能正确实现
  4. 测试覆盖不足:AI 生成的测试用例可能不够全面,需要人工补充边缘场景测试

最佳实践

  1. 测试驱动开发:先编写测试用例,再实现功能,确保每个功能都有验证
  2. 真实报文对照:使用 tcpdump/Wireshark 抓取真实报文,验证协议实现的正确性
  3. 渐进式开发:分阶段开发,每个阶段完成后进行验证,避免一次性实现所有功能
  4. 代码审查:定期审查 AI 生成的代码,确保符合项目规范和最佳实践
  5. 知识积累:将发现的问题和解决方案记录到项目记忆中,供后续开发参考

7.2 工程实践经验

协议兼容性

  1. 文档不可完全信赖:协议文档可能存在错误,需要通过真实抓包验证
  2. 字节级兼容:协议实现必须精确到字节级别,任何细微差异都可能导致互操作失败
  3. 扩展字段处理:正确处理协议扩展字段,确保与原版 iptux 和飞鸽传书兼容
  4. 编码兼容性:支持多种中文编码(GB18030、GBK、Big5),确保跨平台中文显示正确

跨平台开发

  1. 配置路径自适应:根据操作系统自动选择配置和缓存路径(Windows %APPDATA% / Linux ~/.config)
  2. 网络接口适配:Windows 使用 psutil 获取广播地址,Linux 使用 ioctl
  3. Shell 环境差异:不同 Shell 的语法差异,需要采用脚本化策略
  4. PyQt 版本差异:Windows 使用 PyQt6,Linux 使用 PyQt5,需要处理 API 差异

测试策略

  1. 单元测试优先:每个功能模块都有完整的单元测试,确保基础功能正确
  2. 集成测试补充:使用对照机进行真实互操作测试,验证跨平台兼容性
  3. 标记跳过机制 :依赖外部环境的测试用 @pytest.mark 标记,离线时自动跳过
  4. 回归测试保障:全量回归测试确保修改不会破坏已有功能

架构设计

  1. 分层架构:核心层、事件桥接层、UI 层清晰分离,降低耦合度
  2. 事件驱动:使用事件系统解耦核心层和 UI 层,便于测试和扩展
  3. 控制台优先:先实现无 UI 依赖的控制台版本,再构建 GUI
  4. 协议文档化:详细记录协议规范和设计决策,便于后续维护

7.3 未来改进方向

功能增强

  1. 语音消息:支持语音消息的录制和播放
  2. 视频消息:支持视频消息的发送和接收
  3. 文件预览:在发送前预览文件内容
  4. 断点续传:支持文件传输中断后的断点续传
  5. 群文件共享:支持群组内文件共享
  6. 消息加密:支持端到端消息加密
  7. 多语言支持:支持英文、日文等多种语言界面

性能优化

  1. 大文件传输优化:支持更大文件的高效传输
  2. 批量消息处理:优化大量消息的处理性能
  3. 内存管理:优化内存使用,避免大文件传输时的内存占用过高
  4. 并发连接:支持更多并发连接

平台扩展

  1. macOS 支持:添加 macOS 平台支持
  2. 移动端支持:开发 Android/iOS 移动端版本
  3. Web 版本:开发基于 Web 的版本,支持浏览器访问

开发工具

  1. 协议调试器:开发专用的协议调试工具,便于分析和调试协议问题
  2. 性能分析工具:添加性能分析功能,帮助定位性能瓶颈
  3. 自动化测试框架:完善自动化测试框架,支持更多场景的自动测试

社区贡献

  1. 文档完善:完善项目文档,包括用户手册、开发者指南等
  2. 示例代码:提供更多示例代码,帮助开发者理解和扩展项目
  3. Bug 报告:建立完善的 bug 报告和处理流程
  4. 功能请求:建立功能请求和优先级排序机制

7.4 项目成果总结

交付成果

  1. 完整的 Python 版 iptux:与原版 iptux 0.8.3 字节级协议兼容
  2. 跨平台支持:Windows 和 Linux 均可运行
  3. 控制台版本:无 UI 依赖,可在服务器环境运行
  4. GUI 版本:完整的 PyQt6 界面,支持所有核心功能
  5. 测试套件:1118 个单元测试,覆盖所有核心功能
  6. 文档:完整的协议文档、技术方案、开发计划和用户手册

互操作验证

  • ✅ pyqtux ↔ pyqtux:双向发现、消息、文件传输
  • ✅ pyqtux ↔ iptux 0.8.3:双向发现、消息、文件传输、头像、签名
  • ✅ pyqtux ↔ 飞鸽传书:协议兼容(标记为 compat=False)

技术亮点

  1. asyncio 异步网络:高效的异步网络通信,支持大量并发连接
  2. 事件驱动架构:解耦核心层和 UI 层,便于测试和扩展
  3. 协议字节级兼容:与原版 iptux 完全协议兼容
  4. 测试驱动开发:完整的测试套件,确保代码质量
  5. 跨平台自适应:自动适配不同操作系统的差异

开发周期

项目在约 24 小时内完成了从需求分析到发布的全过程,包括:

  • 协议分析和文档编写
  • 6 个阶段、24 个任务的开发
  • 完整的测试验证
  • 三端互操作矩阵验证

这充分展示了 AI 辅助开发的高效性和可行性,为后续项目提供了宝贵的经验参考。


项目仓库

本项目已开源,仓库地址:https://gitcode.com/colorEagleStdio/pyqtux.git

相关推荐
小大宇2 小时前
python flask框架 SSE流式返回、跨域、报错
开发语言·python·flask
zhangfeng11332 小时前
CVOCA 卷积模型,《Nature》子刊 特征提取技术突破性研究的综合分析报告
人工智能
炎火星2 小时前
直播切片素材杂乱,怎么用 AI 剪辑做成可用带货视频?
人工智能
像风一样的男人@2 小时前
python --fastapi推流AI推理
人工智能·python·fastapi
行走的小派2 小时前
从个人开发到企业部署:OPi AI Station四大应用场景与选型指南
人工智能·边缘计算·香橙派·边缘ai
天云数据2 小时前
从“雇佣一个人”到“组建一个团队”:AI生产力的组织方式被重写
人工智能
2601_956319882 小时前
最新量化开发卡住,先查规则和流程是否完整
人工智能·python
柒星栈2 小时前
PHP 源码怎么加密防破解?三套方案实战指南
开发语言·php·android studio
勉灬之2 小时前
Next.js + Prisma 跨平台部署踩坑记
开发语言·javascript·ecmascript