You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python在非局域网远程电脑间快速发送字符串?

跨互联网Windows设备间去中心化字符串传输方案

1. STUN/TURN驱动的P2P直连(首选)

利用STUN协议获取双方设备的公网NAT映射地址,优先尝试直接建立TCP/UDP连接;若直连失败,自动切换到TURN中继节点(仅用于转发数据,无数据存储)。这种方案无需手动配置端口,多数防火墙允许出站流量即可正常工作,且数据传输速度接近直连水平。

C#实现示例(Windows .NET环境)

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

// 简化的STUN客户端逻辑(获取公网映射地址)
public class StunClient
{
    private const string StunServer = "stun.l.google.com";
    private const int StunPort = 19302;

    public static IPEndPoint GetPublicEndpoint()
    {
        using var udpClient = new UdpClient();
        udpClient.Connect(StunServer, StunPort);
        // 发送STUN绑定请求(简化版)
        byte[] request = new byte[] { 0x00, 0x01, 0x00, 0x00 };
        udpClient.Send(request, request.Length);
        
        IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
        byte[] response = udpClient.Receive(ref remoteEP);
        
        // 解析响应中的公网地址(简化逻辑,实际需处理完整STUN协议)
        int ipOffset = 20;
        IPAddress publicIp = new IPAddress(response.AsSpan(ipOffset, 4));
        int publicPort = BitConverter.ToInt16(response.AsSpan(ipOffset + 4, 2));
        return new IPEndPoint(publicIp, publicPort);
    }
}

// 字符串传输客户端
public class P2PClient
{
    public static void SendString(string targetPublicIp, int targetPort, string message)
    {
        using var tcpClient = new TcpClient();
        tcpClient.Connect(targetPublicIp, targetPort);
        byte[] data = Encoding.UTF8.GetBytes(message);
        NetworkStream stream = tcpClient.GetStream();
        stream.Write(data, 0, data.Length);
        stream.Close();
    }
}

// 字符串传输服务端
public class P2PServer
{
    public static void StartListening(int localPort)
    {
        TcpListener listener = new TcpListener(IPAddress.Any, localPort);
        listener.Start();
        Console.WriteLine($"服务端启动,本地端口:{localPort},公网地址:{StunClient.GetPublicEndpoint()}");
        
        while (true)
        {
            TcpClient client = listener.AcceptTcpClient();
            NetworkStream stream = client.GetStream();
            byte[] buffer = new byte[1024];
            int bytesRead = stream.Read(buffer, 0, buffer.Length);
            string received = Encoding.UTF8.GetString(buffer, 0, bytesRead);
            Console.WriteLine($"收到消息:{received}");
            stream.Close();
            client.Close();
        }
    }
}

关键说明

  • 自动获取公网地址:通过公共STUN服务器获取设备的公网映射端口,无需手动配置UPnP
  • 防火墙适配:首次运行时,Windows防火墙会弹出权限请求,允许程序通信即可;也可通过代码调用Windows API自动添加防火墙规则
  • 安全性:传输前对字符串进行AES加密,避免明文传输泄露数据

2. UDP打洞实现(高速小数据传输)

对于短字符串传输,UDP打洞是更高效的方案,无需TCP握手延迟,适合低延迟场景。

C#实现示例

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class UdpHolePuncher
{
    private static UdpClient _udpClient;
    private static IPEndPoint _remoteEndpoint;

    public static void Initialize(int localPort)
    {
        _udpClient = new UdpClient(localPort);
        // 先向已知的公共节点发送消息,触发NAT映射
        _udpClient.Send(Encoding.UTF8.GetBytes("init"), "public-relay-node", 12345);
    }

    public static void SendMessage(string remoteIp, int remotePort, string message)
    {
        _remoteEndpoint = new IPEndPoint(IPAddress.Parse(remoteIp), remotePort);
        _udpClient.Send(Encoding.UTF8.GetBytes(message), message.Length, _remoteEndpoint);
    }

    public static void StartListening()
    {
        IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
        while (true)
        {
            byte[] data = _udpClient.Receive(ref remoteEP);
            string message = Encoding.UTF8.GetString(data);
            Console.WriteLine($"收到消息:{message}");
        }
    }
}

关键说明

  • 打洞逻辑:双方先向同一个公共节点发送UDP包,让各自的NAT记录对方的地址,之后即可直接通信
  • 速度:UDP无握手和重传(可自行实现轻量重传保证可靠),速度远快于TCP
  • 去中心化:仅初始阶段依赖公共节点,后续数据直连

3. 轻量中继备选方案(P2P失败时 fallback)

如果NAT类型为对称型,P2P直连可能失败,此时可使用轻量分布式中继节点(无需中心化服务器),节点由用户群体维护,数据仅临时转发不存储。

C#中继节点简化实现

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections.Generic;

public class RelayNode
{
    private static Dictionary<string, IPEndPoint> _peerMap = new Dictionary<string, IPEndPoint>();
    private static UdpClient _udpServer;

    public static void Start(int port)
    {
        _udpServer = new UdpClient(port);
        Console.WriteLine($"中继节点启动,端口:{port}");
        
        while (true)
        {
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
            byte[] data = _udpServer.Receive(ref remoteEP);
            string message = Encoding.UTF8.GetString(data);
            
            if (message.StartsWith("register:"))
            {
                string peerId = message.Split(':')[1];
                _peerMap[peerId] = remoteEP;
                Console.WriteLine($"注册节点:{peerId} - {remoteEP}");
            }
            else if (message.StartsWith("send:"))
            {
                string[] parts = message.Split(':');
                string targetPeerId = parts[1];
                string content = parts[2];
                if (_peerMap.TryGetValue(targetPeerId, out IPEndPoint targetEP))
                {
                    _udpServer.Send(Encoding.UTF8.GetBytes(content), content.Length, targetEP);
                }
            }
        }
    }
}

关键说明

  • 去中心化:用户可自行搭建多个中继节点,客户端随机选择节点进行注册和转发
  • 无需手动操作:客户端自动发现中继节点列表,无需用户配置
  • 安全性:传输内容加密,中继节点无法解析原始数据

内容的提问来源于stack exchange,提问作者imperial

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 19:57:47