一个简单的剪贴板实时同步工具,可以在多台计算机之间通过网络实时同步剪贴板内容。
ClipMirror 采用客户端-服务器架构,实现剪贴板内容的实时同步:
- 服务端:监听指定端口,接收客户端的剪贴板更新,并将这些更新广播给所有连接的客户端
- 客户端:监控本地剪贴板变化,将更新发送给服务器,同时接收服务器广播的更新并写入本地剪贴板
- Python 3.x
- 依赖库:
- Linux:
xclip(系统包) - macOS: PyObjC (可选,推荐)
pip install pyobjc-core pyobjc-framework-AppKit - Windows: 无额外依赖
- Linux:
# Linux
sudo apt-get install xclip
# macOS (可选,用于更好的文件粘贴支持)
pip install pyobjc-core pyobjc-framework-AppKit在服务端机器上运行:
python server.py <端口号>示例:
python server.py 5000在客户端机器上运行:
python client.py <服务器IP> <端口号>示例:
python client.py 192.168.1.100 5000使用 nohup 在后台运行:
# 后台运行服务器
nohup python server.py 5000 &
# 后台运行客户端
nohup python client.py 192.168.1.100 5000 &- 无加密:剪贴板内容以明文传输,请勿在不受信任的网络环境中使用
- 无身份验证:任何能连接到服务器端口的设备都可以接收剪贴板内容
- 建议仅在本地局域网或受控网络环境中使用
- 客户端每 100ms 轮询一次剪贴板变化
- 心跳包每 30 秒发送一次,用于维持连接
- 服务器监听队列最大为 32 个连接
- 支持 Windows、Linux 和 macOS 系统
- 支持多种剪贴板内容类型:纯文本、图片、文件等
- 不同平台的 socket 错误处理存在差异,已做兼容处理
- macOS 系统从休眠唤醒后可能需要重连,已实现自动重连机制
程序运行时会生成以下日志文件(已加入 .gitignore):
log_client.txt- 客户端运行日志log_server.txt- 服务器运行日志nohup.out- nohup 后台运行时的输出
采用 TCP Socket 进行可靠通信,消息格式如下:
| 1字节类型长度 | 类型后缀(UTF-8) | 4字节数据长度(大端序) | 原始数据 |
- 第 1 字节表示类型后缀的长度
- 类型后缀:
_plaintext表示纯文本,其他如png、txt、zip等表示文件类型 - 4 字节数据长度:表示原始数据的字节长度
- 原始数据:文本为 UTF-8 编码,其他为二进制数据
\xff\xff(2字节) 用作心跳包
- 使用
select.select()实现非阻塞 I/O,支持多客户端并发 MessageParser处理可能不完整的消息(粘包/半包问题)- 使用独立线程向各客户端广播消息,避免阻塞主循环
- 支持最多 32 个并发连接
ClipboardMonitor:每 100ms 检查本地剪贴板变化MessageMonitor:处理与服务器的通信,支持自动重连EventMonitor:协调剪贴板监控和消息接收
- 客户端每 30 秒发送一次心跳包
- 服务器识别心跳包后不进行广播处理
- 用于维持长连接,检测连接状态
客户端检测到以下情况时会自动重连:
- 连接被远程关闭
- 连接重置 (ConnectionResetError)
- Socket 错误(如系统唤醒后的地址不可用)
- 发送消息失败
重连策略为每 0.5 秒尝试一次,直到成功或用户中断。
BlockingIOError(Linux) /TimeoutError(macOS):非阻塞 socket 无数据时的正常行为ConnectionResetError:客户端断开连接,服务器自动清理连接OSError:处理系统唤醒后的连接问题
clipmirror/
├── client.py # 客户端程序
├── server.py # 服务端程序
├── .gitignore # Git 忽略文件配置
└── README.md # 项目说明文档
前台运行时使用 Ctrl+C 终止程序。
后台运行时可使用 ps 查找进程 ID 后用 kill 终止。
项目目前处于活跃开发阶段,最近的修复包括:
- UTF-8 字符串处理
- 心跳机制实现
- macOS 超时错误处理
- 日志输出优化
- 连接重置处理
本项目仅供学习和个人使用。