TCP打孔(NAT Traversal)库还是什么?

Tob*_*idi 34 c# tcp nat

我想在C#中进行TCP打孔(NAT Traversal).如果需要,可以使用集合服务器完成.我找到了http://sharpstunt.codeplex.com/但无法让它工作.理想情况下,我需要一些方法,我将一个端口号(int)作为参数,在NAT上调用此方法后可用("Port Forwarded").如果该方法只返回一些后来在NAT上可用的端口号,那也没关系.有没有人用C#做过这个?你能给我一些sharpstunt或其他东西的例子吗?

Sil*_*erX 20

在每种网络场景中,TCP打孔操作的方式与UDP打孔方式类似.例如,如果两个对等体A和B落后于不同的NAT,则发送到另一个对等体的每个对等体的第一个SYN数据包在其各自的NAT中打开与其公共地址相关联的漏洞.如果A到B的第一个SYN数据包到达B的NAT,那么在B的第一个SYN数据包到A的B到达NAT之前,B的NAT认为A的SYN数据包是未经请求的并且丢弃了它.但是,随后B的第一个SYN数据包可以成功通过A的NAT,因为A的NAT将B的公共地址识别为A发起的传出会话的目的地.

是的 TCP打孔是可能的.我不明白为什么有人会这么想.

另外,你不能手动创建这种类型的bahaviour吗?只要步骤相同以收集所有必需信息,它就不需要依赖任何特定协议.

一般而言,TCP打孔(3.2.1)的过程如下:

客户端:A,B服务器:S

•A使用其与S的连接来请求S与B建立连接.•S使用B的私有和公共地址回复A,同时将A的地址发送给B.

•A和B异步地将传出连接尝试(发送SYN数据包)发送到彼此的公共和专用地址,从它们用于向S注册的同一端口.同时,它们侦听TCP的传入连接尝试.本地TCP端口.

•A和B等待对其外出SYN数据包或传入连接请求(SYN数据包)的SYN-ACK响应.如果连接失败,则对等方可以重试连接到最大超时时间.

•三次握手过程完成后,对等方互相进行身份验证.如果验证失败,则对等体关闭该连接并等待,直到另一个连接成功通过验证.第一个成功通过身份验证的连接将用于传输TCP数据.

(我知道这不是一个答案,但没有足够的空间发表评论).

  • 我只是描述打孔过程。特技是一套实际的工具,用于帮助打孔过程。我的回答的主要观点是表明 TCP 打孔确实是可能的,因为有人提到它不是。我知道在某些情况下它不起作用,但这不是问题。(至于为什么提到私人地址。我不知道。我从其他来源复制了大部分数据)。 (2认同)

JPe*_*ier 5

这个问题已经很老了,但对于任何寻找 NAT 穿越替代解决方案的人来说,您应该看看Open.NAT 项目。它确实很容易使用,并且可以与 UPNP 和 PMP 一起使用,但它与打孔不同。

假设您要将外部端口 1700 转发到本地端口 1600,您所要做的就是:

var discoverer = new NatDiscoverer();
var device = await discoverer.DiscoverDeviceAsync();
await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, 1600, 1700, "The mapping name"));
Run Code Online (Sandbox Code Playgroud)

您还可以列出所有现有映射,以便验证您的端口是否尚未使用。

var sb = new StringBuilder();
var ip = await device.GetExternalIPAsync();

sb.AppendFormat("\nAdded mapping: {0}:1700 -> 127.0.0.1:1600\n", ip);
sb.AppendFormat("\n+------+-------------------------------+--------------------------------+------------------------------------+-------------------------+");
sb.AppendFormat("\n| PROT | PUBLIC (Reacheable)           | PRIVATE (Your computer)        | Descriptopn                        |                         |");
sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+");
sb.AppendFormat("\n|      | IP Address           | Port   | IP Address            | Port   |                                    | Expires                 |");
sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+");
foreach (var mapping in await device.GetAllMappingsAsync())
{
    sb.AppendFormat("\n|  {5} | {0,-20} | {1,6} | {2,-21} | {3,6} | {4,-35}|{6,25}|",
        ip, mapping.PublicPort, mapping.PrivateIP, mapping.PrivatePort, mapping.Description, mapping.Protocol == Protocol.Tcp ? "TCP" : "UDP", mapping.Expiration.ToLocalTime());
}
sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+");
Console.WriteLine(sb.ToString());
Run Code Online (Sandbox Code Playgroud)

MSDN 上还有一篇关于 NAT Traversal 的博文:https://blogs.msdn.microsoft.com/ncl/2009/07/27/end-to-end-connectivity-with-nat-traversal/

  • 需要明确的是,UPnP 与防火墙打洞不同。它们都是 NAT 穿越的形式,但是 UPnP 只是在 NAT 中创建端口转发条目的一种方式,而打洞可以连接两个对等点,而无需显式定义这些条目。 (3认同)