没有端口/转发的 C# P2P

Posted

技术标签:

【中文标题】没有端口/转发的 C# P2P【英文标题】:C# P2P without port/forwarding 【发布时间】:2015-11-08 14:00:14 【问题描述】:

我已经制作了一个相互连接的服务器和客户端应用程序,但是我必须在路由器中打开端口才能使其工作。

我可以使用不需要转发的端口吗? 或者我可以应用的技术?

我想保持 p2p 并避免在请求中间有服务器。

【问题讨论】:

【参考方案1】:

我知道可以在这里应用两种技术。

技术 1UDP 打孔

UDP Hole Punching 使用服务器作为“大厅”。 您想要进行 P2P 连接的客户端首先使用 UDP 协议连接到服务器,因此客户端需要打开一个端口(“洞”)才能接收数据。

由于 UDP 是一种无连接协议,您可以将客户端设置为接受从“大厅”服务器传入的数据包以及彼此之间的数据包。

在两个客户端都建立连接后,服务器将为它们提供其伙伴的 IP 和匹配的“hole”-port。

可以在答案here 中找到一个非常简单的实现。

技术 2通用即插即用

两者中我最不喜欢的,因为它要求客户端的路由器支持 uPnP 并启用它。

C#.NET 中的 uPnP 可以通过包含 NATUPNPLib COM 库轻松完成 (不要忘记在参考设置中禁用“嵌入互操作类型”)

一个简单的实现是这样的:

    public const int upnp_port = 3075;

    private static UPnPNATClass pnp = new UPnPNATClass();
    private static IStaticPortMappingCollection mapc = pnp.StaticPortMappingCollection;

    public static IPAddress local_ip()
    
        foreach (IPAddress addr in Dns.GetHostEntry(string.Empty).AddressList)
            if (addr.AddressFamily == AddressFamily.InterNetwork)
                return addr;
        return null;
    

    public static void upnp_open()
    
        mapc.Add(upnp_port, "UDP", upnp_port, local_ip().ToString(), true, "P2P Service Name");
    

    public static void upnp_close()
    
        mapc.Remove(upnp_port, "UDP");
    

注意,这是快速编写的代码,需要忽略/优化,绝对是 local_ip() 函数,因为安装了多个网络适配器后它会变得不可靠。

【讨论】:

以上是关于没有端口/转发的 C# P2P的主要内容,如果未能解决你的问题,请参考以下文章

NAT 穿透原理浅浅说 ---转发

所有 NAT 类型的 P2P 连接

打开 Internet P2P 套接字连接

来自 C# 的端口转发

串口服务器配置

Nginx端口转发, 怎么做到不用二级目录?