· shi2 yong4 gong1 ju4  · 6 min read

多设备共享粘贴板实现方案:局域网UDP广播 (开发者向)

苹果设备间的共享剪切板确实方便,但是无法用到我的linux台式机上,造成了很多不便。本文提供了一种利用局域网UDP广播实现多设备共享粘贴板的方法,并使用对称加密算法保证数据传输安全。

苹果设备间的共享剪切板确实方便,但是无法用到我的linux台式机上,造成了很多不便。本文提供了一种利用局域网UDP广播实现多设备共享粘贴板的方法,并使用对称加密算法保证数据传输安全。

共享剪贴板可以让您在多台设备之间共享文本、图像和其他文件。以下是一些常见的方法:

  1. 使用云服务:您可以使用云服务如Google Drive、OneDrive或Dropbox来共享文本或文件。在您的云存储中创建一个文件夹,然后将您想要共享的内容拖放到该文件夹中。您可以通过登录到同一帐户的不同设备来访问该文件夹,并将内容复制到您的剪贴板中。

  2. 使用第三方应用程序:有许多第三方应用程序,如Pushbullet、Clipper和Join,可以帮助您在不同设备之间共享剪贴板。这些应用程序可以在您的移动设备和电脑之间同步,并允许您将文本、图像和其他文件直接从一个设备复制到另一个设备的剪贴板。

  3. 使用操作系统自带的功能:某些操作系统(如Windows 10)具有内置的剪贴板历史记录功能,可让您访问最近复制的文本和图像。您可以使用此功能在不同设备之间复制内容。

请注意,使用任何共享剪贴板方法都需要连接到互联网,并且可能需要安装额外的软件或应用程序。另外,因为共享剪贴板涉及到您的个人信息和文件,您应该确保您的数据受到保护并只与信任的人共享。

考虑到第三方应用的系统兼容和数据安全,还是自己实现比较稳妥,一劳永逸。

苹果设备间的共享粘贴板确实方便,但是无法用到我的linux台式机上,造成了很多不便。既然都是在局域网中的设备,就想到了通过局域网同步粘贴板,以下的代码通过python读取系统粘贴板并广播到局域网。

使用指南

1. 安装python
  • macos安装 sudo brew install python3
  • linux(ubuntu/debian)安装 sudo apt install python3
2. 安装python依赖包

python3 -m pip install netifaces pyperclip pycryptodome

3. 在不同的机器上分别启动

python3 main.py

4. 关闭防火墙或者防火墙允许udp 9999端口

sudo ufw allow 9999/udp

可以参考另一篇文章中的防火墙设置mosh的防火墙设置

运行

python3 main.py

5. TODO: buffer for udp protocol datagram length limit

main.py完整代码

import asyncio
import pyperclip as clip
import socket
import fcntl
import struct
import platform
import netifaces
from Crypto.Cipher import AES
from base64 import b64encode, b64decode

# 加密传输(使用对称加密AES即可)
# 局域网中的udp广播,所有的局域网机器都可以监听到数据,必须加密
key = b'Slxt33n Byte kEy' # your own secret: must 16 bytes length
mode = AES.MODE_OCB
def encrypt(text: str):
    cipher = AES.new(key, mode)
    nonce = cipher.nonce
    ciphertext, tag = cipher.encrypt_and_digest(text.encode('utf-8'))
    signs = [b64encode(x).decode() for x in [nonce, ciphertext, tag]]
    return ':'.join(signs).encode()
    
def decrypt(text: str):
    print(text)
    nonce, ciphertext, tag = [ b64decode(x.encode()) for x in text.split(':')  ] 
    cipher = AES.new(key, mode, nonce=nonce)
    plaintext = cipher.decrypt_and_verify(ciphertext, tag)
    return plaintext.decode('utf-8')

def get_ip():
    system = platform.system()
    if system == 'Linux':
        interface = 'wlp37s0' # linux使用命令查看局域网对应的网卡名称:ip address
    elif system == 'Darwin':
        interface = 'en0' # macos使用命令查看局域网对应的网卡名称:ifconfig -a
    return netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr']

class EchoServerProtocol:
    def connection_made(self, transport):
        self.transport = transport
        self.hostip = get_ip()
        print(f'host ip: {self.hostip}')
        self.buffer = []

    def datagram_received(self, data, addr):
        # only copy content from other machine
        # 只复制其他机器发来的数据
        if addr[0] != self.hostip:
            message = decrypt(data.decode())
            # if message.
            print('Received %r from %s' % (message, addr))
            clip.copy(message)


async def main():
    print("Starting UDP server")

    # Get a reference to the event loop as we plan to use
    # low-level APIs.
    loop = asyncio.get_running_loop()

    # One protocol instance will be created to serve all
    # client requests.
    transport, protocol = await loop.create_datagram_endpoint(
        lambda: EchoServerProtocol(),
        remote_addr=('255.255.255.255', 9999), # broadcast to ethernet's udp port 9999
        local_addr=('0.0.0.0', 9999),          # accept all comming addresses
        allow_broadcast=True)

    try:
        oldpaste = clip.paste()
        # 无限循环,查看本机粘贴板
        while True:
            await asyncio.sleep(1)
            paste = clip.paste()
            if oldpaste != paste:
                print(f'system clipboard content: {paste}')
                transport.sendto(encrypt(paste))
                oldpaste = paste
    finally:
        transport.close()

# 主程序启动
asyncio.run(main())

奇妙的事情发生了

当mac电脑和linux电脑都运行上边的程序后,我的苹果手机上复制的内容马上就到达linux电脑上了,反之亦然。相当于三个设备共享了粘贴板,加上我的ipad就成了四个设备,香。

Back to Blog

Related Posts

View All Posts »
Mosh: SSH远程登录的替代者

Mosh: SSH远程登录的替代者

Mosh的连接可在网络断开连接后自动重连,而不会中断会话,Mosh在高延迟和不稳定的网络条件下具有更快的响应速度和更少的延迟,这使得在远程连接中使用命令行工具更加流畅,并且Mosh会根据当前网络状况自适应调整连接参数,这有助于提高连接质量

Python最新包管理工具推荐:rye

Python最新包管理工具推荐:rye

使用官方包管理工具pip,同一个包只能存在一个版本,同一个项目中一旦出现版本不兼容,即使使用virtual env也无济于事。rye发布在Github一周多的时间内,收获4.5k的star,由此可见社区对Python包管理工具的渴求。它安装并管理Python多版本,管理pyproject.toml文件,安装和卸载依赖项,并在幕后管理virtualenvs。它支持repo内包安装和全局工具安装。

使用门罗币XMR进行监控收款(入门篇)

使用门罗币XMR进行监控收款(入门篇)

使用USDT收款相对比较简单,只需监控特定地址在USDT智能合约上的交易记录,只统计向该地址转账的交易并与订单信息进行比对,即可完成收款。然而,门罗币的匿名性导致第三方监控无法获取发送方地址和金额,交易信息只能通过接收方使用私钥进行监控。