远程端点给出错误的 IP 地址
本文关键字:错误 出错 IP 地址 程端点 端点 | 更新日期: 2023-09-27 17:56:04
我们正在使用Fleck作为我们的Websockets。
当我们在本地测试我们的网络程序时,一切正常。 客户端连接的过程是:
- 建立 TCP 连接
- 发送/接收不频繁的 TCP 消息
- 开始向服务器发送/接收 UDP 流
问题出在地理位置很远的实时服务器上,客户端可以接收和发送TCP
消息,它们可以发送 UDP 消息,但不接收 UDP 消息。
我们已经尽可能地调查了它,发现服务器上TCP连接的RemoteEndPoint
属性具有错误的IP地址。 它似乎是来自我们ISP的IP地址。 我们使用此 IP 地址尝试将 UDP 消息发送回客户端。 由于它具有错误的 IP,客户端永远不会收到这些 UDP 消息。
客户端的实际源 IP 地址必须在某处知道,因为 TCP 消息使其返回正常。 我已经浏览了 Fleck 源代码并打印出了底层System.Net.Socket
的RemoteEndPoint
,但它一直给出错误的 IP 地址。
有谁知道出了什么问题以及我们如何公开客户端的实际 IP 地址?
最可能的原因是您的客户端没有公共 IP 地址,而是网络地址转换后面的专用地址(一种非常常见的设置)。常见的私有地址格式为 10.X.X.X 或 192.168.X.X。
NAT 设备将来自客户端的数据包中的专用地址替换为其公共 IP 地址。对于外部世界来说,流量似乎来自NAT设备。NAT 的主要优点是它允许许多客户端使用单个公共 IP 地址(IP 地址稀疏)。但是 NAT 引入了一个问题:传入数据包需要路由到正确的客户端,但它没有客户端 IP 地址。需要使用其他一些策略来识别数据包应路由到哪个客户端,并且这种路由并不总是可能的。
例如,NAT 最广为人知的限制是,您不能简单地在 NAT 后面启动侦听 TCP 服务器,然后从外部世界连接到它。原因是NAT设备不知道您的服务器侦听给定的端口,因此,它无法知道来自外部世界的TCP SYN数据包需要传递给您的客户端。解决此问题的方法是显式配置 NAT 设备,以将定向到给定端口的 SYN 数据包路由到特定客户端(端口转发)。
当 NAT 后面的客户端启动 TCP 连接时,NAT 设备会记住连接的状态(客户端地址、客户端端口、远程地址、远程端口)。因此,当响应到达时,设备知道响应应传递到哪个客户端。当连接关闭时,设备将丢弃状态信息。这就是客户端可以通过 TCP 进行通信的原因。
但是 UDP 更难处理,因为它是无连接和无状态的。当设备看到 UDP 数据包时,它现在知道是否预期回复以及何时回复,因此并非所有 NAT 设备都处理 UDP 流量。虽然有一种技术可以做到这一点。
总而言之:您看到的问题不是特定于 C# 的。在从服务器到客户端 IP 地址的数据包中设置 IP 地址无济于事,因为它很可能是不可路由的专用地址。要解决此问题,您需要使用可以在两个方向上传递 UDP 流量的 NAT 设备。但是,如果您正在开发要在许多设置中使用的通用客户端,则可能需要重新考虑 UDP 是否是最佳选择。TCP 连接转发是所有 NAT 设备都支持的基本功能,但某些设备可能不支持 UDP。