本文目录导读:

局域网跨设备剪贴板(推荐)
服务端(接收端)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
跨设备剪贴板 - 服务端(接收端)
运行在需要接收剪贴板内容的设备上
"""
import socket
import threading
import pyperclip
import json
import time
from datetime import datetime
class ClipboardServer:
def __init__(self, host='0.0.0.0', port=8888):
self.host = host
self.port = port
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.clients = []
self.running = True
def start(self):
"""启动服务器"""
try:
self.server_socket.bind((self.host, self.port))
self.server_socket.listen(5)
print(f"✋ 剪贴板服务器已启动: {self.host}:{self.port}")
print("等待其他设备连接...")
# 启动接收线程
accept_thread = threading.Thread(target=self.accept_clients)
accept_thread.daemon = True
accept_thread.start()
# 主循环,监听剪贴板变化
self.monitor_clipboard()
except Exception as e:
print(f"❌ 服务器错误: {e}")
self.running = False
def accept_clients(self):
"""接受客户端连接"""
while self.running:
try:
client_socket, address = self.server_socket.accept()
client_id = f"{address[0]}:{address[1]}"
self.clients.append(client_socket)
print(f"✅ 新设备连接: {client_id}")
print(f"📊 当前连接数: {len(self.clients)}")
# 启动接收该客户端数据的线程
client_thread = threading.Thread(target=self.handle_client, args=(client_socket, address))
client_thread.daemon = True
client_thread.start()
except:
break
def handle_client(self, client_socket, address):
"""处理客户端数据"""
try:
while self.running:
data = client_socket.recv(4096)
if not data:
break
# 解码并设置剪贴板
try:
content = data.decode('utf-8')
pyperclip.copy(content)
print(f"📋 [{datetime.now().strftime('%H:%M:%S')}] 收到剪贴板内容: {content[:50]}...")
# 广播给其他客户端(可选)
self.broadcast(content, client_socket)
except Exception as e:
print(f"⚠️ 处理数据错误: {e}")
except Exception as e:
print(f"❌ 客户端连接断开: {e}")
finally:
if client_socket in self.clients:
self.clients.remove(client_socket)
client_socket.close()
def broadcast(self, content, exclude_socket):
"""广播消息给其他客户端"""
for client in self.clients[:]:
if client != exclude_socket:
try:
client.send(content.encode('utf-8'))
except:
self.clients.remove(client)
def monitor_clipboard(self):
"""监听本地剪贴板变化"""
last_content = pyperclip.paste()
print("📋 正在监听本地剪贴板...")
print("按 Ctrl+C 退出")
while self.running:
try:
current = pyperclip.paste()
if current != last_content and current:
print(f"📋 本地剪贴板变化: {current[:50]}...")
# 广播给所有客户端
self.broadcast(current, None)
last_content = current
time.sleep(1) # 1秒检查一次
except KeyboardInterrupt:
print("\n👋 服务器关闭")
self.running = False
break
except Exception as e:
print(f"⚠️ 监听错误: {e}")
last_content = pyperclip.paste()
def stop(self):
"""停止服务器"""
self.running = False
for client in self.clients:
client.close()
self.server_socket.close()
def main():
print("=" * 50)
print("跨设备剪贴板 - 服务端")
print("=" * 50)
# 使用默认配置或从环境变量读取
host = input(f"监听地址 (默认: 0.0.0.0): ").strip() or '0.0.0.0'
port = input(f"端口 (默认: 8888): ").strip() or '8888'
port = int(port)
server = ClipboardServer(host, port)
try:
server.start()
except KeyboardInterrupt:
print("\n👋 程序退出")
finally:
server.stop()
if __name__ == "__main__":
main()
客户端(发送端)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
跨设备剪贴板 - 客户端(发送端)
运行在需要发送剪贴板内容的设备上
"""
import socket
import pyperclip
import threading
import time
from datetime import datetime
class ClipboardClient:
def __init__(self, server_host, server_port=8888):
self.server_host = server_host
self.server_port = server_port
self.socket = None
self.running = True
self.last_content = ""
def connect(self):
"""连接到服务器"""
try:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect((self.server_host, self.server_port))
print(f"✅ 已连接到服务器: {self.server_host}:{self.server_port}")
# 启动接收线程(可选)
recv_thread = threading.Thread(target=self.receive_data)
recv_thread.daemon = True
recv_thread.start()
return True
except Exception as e:
print(f"❌ 连接失败: {e}")
return False
def receive_data(self):
"""接收服务器广播的数据"""
try:
while self.running:
data = self.socket.recv(4096)
if data:
content = data.decode('utf-8')
print(f"📋 收到数据: {content[:50]}...")
# 可选:更新剪贴板
pyperclip.copy(content)
except:
pass
def send_clipboard(self):
"""发送剪贴板内容"""
last_content = pyperclip.paste()
print("📋 监听剪贴板变化...")
print("按 Ctrl+C 退出")
while self.running:
try:
current = pyperclip.paste()
if current != last_content and current:
# 发送剪贴板内容
self.socket.send(current.encode('utf-8'))
print(f"📤 [{datetime.now().strftime('%H:%M:%S')}] 已发送: {current[:50]}...")
last_content = current
time.sleep(1) # 1秒检查一次
except KeyboardInterrupt:
print("\n👋 客户端退出")
self.running = False
break
except Exception as e:
print(f"⚠️ 发送错误: {e}")
# 尝试重连
if self.running:
print("🔄 尝试重新连接...")
self.running = False
time.sleep(3)
break
def stop(self):
"""停止客户端"""
self.running = False
if self.socket:
self.socket.close()
def main():
print("=" * 50)
print("跨设备剪贴板 - 客户端")
print("=" * 50)
# 获取服务器地址
server_host = input("请输入服务器IP地址: ").strip()
if not server_host:
print("❌ IP地址不能为空")
return
port = input(f"端口 (默认: 8888): ").strip() or '8888'
port = int(port)
client = ClipboardClient(server_host, port)
try:
if client.connect():
client.send_clipboard()
except KeyboardInterrupt:
print("\n👋 程序退出")
finally:
client.stop()
if __name__ == "__main__":
main()
使用说明
安装依赖
pip install pyperclip
启动服务端(接收端)
python clipboard_server.py
启动客户端(发送端)
python clipboard_client.py
使用流程
- 在接收端运行服务端程序
- 在发送端运行客户端程序并输入服务端IP后,会自动同步到其他设备
使用现有工具
如果您不想自己实现,可以使用以下现成的跨设备剪贴板工具:
- KDE Connect - Linux/Windows/Android 跨平台
- AirDroid - Windows/Android
- Pushbullet - 跨平台支持
- Syncthing - 文件同步,可作为备选方案
简单Web版(浏览器访问)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
简单Web版跨设备剪贴板
"""
from flask import Flask, request, jsonify, render_template_string
import pyperclip
import threading
import time
app = Flask(__name__)
HTML_TEMPLATE = '''
<!DOCTYPE html>
<html>
<head>跨设备剪贴板</title>
<meta charset="utf-8">
<style>
body { font-family: Arial, sans-serif; padding: 20px; max-width: 800px; margin: 0 auto; }
textarea { width: 100%; height: 200px; margin: 10px 0; }
button { padding: 10px 20px; margin: 5px; }
#status { color: green; }
</style>
</head>
<body>
<h1>📋 跨设备剪贴板</h1>
<div id="status">已连接</div>
<textarea id="content" placeholder="输入或粘贴内容..."></textarea>
<br>
<button onclick="send()">📤 发送</button>
<button onclick="receive()">📥 接收</button>
<button onclick="clearAll()">🗑️ 清空</button>
<script>
async function send() {
let content = document.getElementById('content').value;
let res = await fetch('/send', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({content: content})
});
let data = await res.json();
document.getElementById('status').innerText = '✅ 发送成功';
}
async function receive() {
let res = await fetch('/receive');
let data = await res.json();
document.getElementById('content').value = data.content;
document.getElementById('status').innerText = '✅ 接收成功';
}
function clearAll() {
document.getElementById('content').value = '';
document.getElementById('status').innerText = '🗑️ 已清空';
}
</script>
</body>
</html>
'''
@app.route('/')
def index():
return render_template_string(HTML_TEMPLATE)
@app.route('/send', methods=['POST'])
def send():
data = request.json
if data and 'content' in data:
pyperclip.copy(data['content'])
return jsonify({'status': 'ok'})
return jsonify({'status': 'error'})
@app.route('/receive')
def receive():
content = pyperclip.paste()
return jsonify({'content': content})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
使用方法:
pip install flask pyperclip python clipboard_web.py
然后通过浏览器访问 http://设备IP:5000 即可使用。
选择哪种方案取决于您的具体需求,如果需要在局域网内频繁使用,推荐方案一;如果偶尔使用,Web方案更方便。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播