我有一个 C# 控制台应用程序,我正在尝试实现 TCP 打孔。
我需要侦听本地端口,并同时(同时/异步)使用相同的本地端口连接到 2 个不同的远程主机(实际上是远程主机公共和专用端点)。
据我了解,我需要以某种方式绑定套接字/端口,但我无法在 C# 中解决这个问题。
有 TCPListener、TCPClient 和 Socket 类,但我不知道使用哪些来完成我的需要。
我正在遵循本指南http://www.bford.info/pub/net/p2pnat/index.html第4.2章
- 从 A 和 B(客户端)用于注册(服务器)的相同本地 TCP 端口 S、A 和 B 每个异步地向对方的公共和专用端点发出传出连接尝试,如下所示由 S 报告,同时侦听各自本地 TCP 端口上的传入连接。
我已经使用 NodeJS 实现了服务器部分,并且工作正常,我正在努力解决上面提到的本地端口问题。
我非常确定 TCP 只允许客户端和服务器以及端口之间的 1-2-1 连接。设置多个连接的唯一方法是创建两个不同的套接字。
你提到的TCP打孔我以前也尝试过。您基本上需要使用中继服务器来告诉 A 和 B 如何连接..因此请执行以下操作:
1) 客户端 A 通过一个端口连接到服务器
2)服务器告诉客户端B您的IP和端口(这将是您将要建立的新连接,与您与服务器的连接不同)
3)服务器告诉客户端A客户端B将使用的IP和端口
4) 客户端 A 使用提供的信息创建直接到客户端 B 的新连接
5)客户端 B 使用有关您的“新”连接的信息来尝试接受传入请求
6)由于延迟,它可能会失败几次握手,因此构建某种中继器来继续尝试连接
7) 您最终应该与 B 有直接连接
您需要创建两个或更多套接字,为其设置 SocketOptionName.ReuseAddress 选项,然后将它们全部绑定到同一 ip:port 对。然后用其中一个套接字进行侦听,并与其他套接字连接到服务器或其他对等点,这使您的公共 ip:port 对(可能与本地不同,因为您位于 NAT 之后)可见。因此其他对等方可以启动与之的连接,这会导致另一个侦听套接字上的传入连接。
为了实现此目的,您的 NAT 需要符合 RFC5382 中描述的实践。