所以最近我一直在开发一个简单的 UDP 服务器和客户端应用程序(使用带有 .NET 的 C#),但是我似乎走进了死胡同,需要建议。
目前的情况是,客户端正在监听端口 xx,而服务器正在监听另一个名为 x 的端口。请参阅此图像。
客户端知道服务器的公网IP,并且转发端口x,以便服务器能够接收客户端通过端口x发送的消息。
作为客户端发送的任何消息的一部分,客户端的公共 IP 被发送到服务器,以便服务器可以向该客户端发送回响应。
我目前的测试表明,这种方法运行良好,直到在一个公共 IP 后面有两个客户端。
这会导致问题,因为服务器发送的数据包要么到达错误的计算机,要么根本没有被接收(我认为路由器只是丢弃它们,因为它无法确定将它们发送到哪一台)。
那么您能给我什么建议/方法来解决此问题?
此致敬礼,阿什利。
答案1
我对你的问题的解释是,你有一个针对 IPv4 的、基本可行的解决方案,但它在某些涉及 NAT 的极端情况下会失效。你可以预见到,未来你的 IPv4 解决方案将面临越来越多的极端情况,而这些情况将变得越来越难以解决。例如,你可能从未通过 NAT444、NAT64、NAT464-XLAT 或 DSLITE 测试过你的解决方案,你可以预见到用户会采用此类配置。
我的建议是在开始研究支持 IPv4 的一些特殊情况之前先实现 IPv6 支持。
一旦您拥有 IPv6 支持,IPv4 的一些极端情况将不再重要。例如,您永远不需要担心使用 NAT64 的客户端与使用 NAT464-XLAT 的另一个客户端之间的通信。
有时可以使用 UDP 打洞技术来实现 NAT 后面两个客户端之间的通信。但只有当两个 NAT 设备中至少有一个以可预测的方式工作时,它才能起作用。如果两个 NAT 设备都以不可预测的方式分配端口号,那么两个设备之间完全不可能实现直接通信。
我将构建对以下连接方法的支持:
- 直接 IPv6 到 IPv6 连接(如果防火墙要求,则从两端同时发起连接)。
- 直接 IPv4 到 IPv4 连接(如果防火墙要求,则从两端同时发起连接)。
- 从 NAT44/NAT444/NAT464 后面的对等端到公共 IPv4 地址上的对等端建立连接。(只要一个对等端有公共 IPv4 地址,另一个对等端位于这三种 NAT 中的哪一种之后就无关紧要了)。
- 已建立从 NAT64 后面的对等端到公共 IPv4 地址上的对等端的连接。(这要求您在公共 IPv4 地址上为对等端创建 DNS 记录,仅 IPv6 对等端可以通过 DNS64 进行解析)。
- 对于无法使用上述任何一种服务的客户端,可通过您托管的双栈服务器进行间接连接。(向没有原生 IPv6 地址的用户收取更高的费用以支付这些服务器的费用才是公平的。)
上述内容听起来可能有点复杂。但远没有解决 IPv4 NAT 行为的每个极端情况那么复杂。(如果在人们开始使用 NAT 之前,大多数用户都已经部署了 IPv6,那么上述不同连接方法的列表就会短得多。)
答案2
在发送数据包时,您希望客户端使用源 UDP 端口 A 发送到服务器上的目标端口 B。然后当服务器响应时,让它使用源 UDP 端口 B 发送到客户端上的目标端口 A。
您应该在服务器和客户端之间安装 NAT 防火墙/路由器。NAT 防火墙/路由器应该具有公共 IP,服务器也应该具有公共 IP,但客户端具有 LAN IP 地址。当每个客户端向服务器发送信息时,它们不需要包含其公共 IP。NAT 防火墙/路由器将更改传出数据包的源 IP 地址,使其看起来来自 NAT 防火墙/路由器公共 IP。然后,当服务器发回时,只要它响应客户端并在合理的时间内发回,NAT 防火墙/路由器就会知道将响应发回哪个客户端。这是使用连接跟踪和状态数据包检查来完成的。
port B
SERVER
public ip1
|
|
public ip2
NATROUTER
/ \
CLIENT1 CLIENT2
lan ip1 lan ip2
port A
抱歉,图不太好!