RemoteEndPoint提供错误的IP地址

时间:2013-01-24 14:33:52

标签: c# sockets networking tcp udp

我们正在使用Fleck作为我们的Websockets。

当我们在本地测试我们的网络程序时,一切正常。客户端连接的过程是:

  • 建立TCP连接
  • 发送/接收不常见的TCP消息
  • 开始向服务器发送/接收UDP流

问题出现在地理位置较远的实时服务器上,客户可以接收和发送TCP消息,而可以发送UDP消息,但是他们 接收 UDP消息。

我们已经尽可能地调查了它,并且发现服务器上TCP连接的RemoteEndPoint属性具有错误的IP地址。它似乎是我们ISP的IP地址。我们使用此IP地址尝试将UDP消息发送回客户端。由于IP错误,客户端永远不会收到这些UDP消息。

必须在某处知道客户端的实际源IP地址,因为TCP消息使其恢复正常。我已经浏览了Fleck来源并打印出基础RemoteEndPoint的{​​{1}},但它一直提供错误的IP地址。

有谁知道出了什么问题以及我们如何公开客户的实际IP地址?

1 个答案:

答案 0 :(得分:1)

最可能的原因是您的客户端没有公共IP地址,而是网络地址转换背后的私有地址(一种非常常见的设置)。常见的私有地址的格式为10.X.X.X或192.168.X.X。

NAT设备使用其IP地址替换来自客户端的数据包中的私有地址,该IP地址是公共的。对于外部世界,似乎流量来自NAT设备。 NAT的主要优点是它允许许多客户端使用单个公共IP地址(IP地址稀疏)。但NAT引入了一个问题:传入的数据包需要路由到正确的客户端,但它没有客户端IP地址。需要使用其他一些策略来识别应该将数据包路由到哪个客户端,并且这种路由并不总是可行。

例如,最着名的NAT限制是您不能简单地在NAT后面启动侦听TCP服务器,然后从外部世界连接到它。原因是NAT设备不知道您的服务器在给定端口上侦听,因此无法知道来自外部世界的TCP SYN数据包需要传递到您的客户端。解决方法是明确配置NAT设备将指向给定端口的SYN数据包路由到特定客户端(端口转发)。

当NAT后面的客户端发起TCP连接时,NAT设备会记住连接状态(客户端地址,客户端端口,远程地址,远程端口)。因此,当响应到达时,设备知道响应应该通过哪个客户端。当连接关闭时,设备会丢弃状态信息。这就是您的客户端可以通过TCP进行通信的原因。

但UDP更难处理,因为它是无连接和无状态的。当设备看到UDP数据包时,它现在知道是否需要回复以及何时回复,因此并非所有NAT设备都处理UDP流量。虽然there is a technique允许这样做。

总结一下:您看到的问题不是C#特定的。将服务器中的IP地址设置为客户端IP地址无济于事,因为它很可能是不可路由的私有地址。要解决此问题,您需要使用可以在两个方向上传递UDP流量的NAT设备。但是,如果您正在开发在许多设置中使用的通用客户端,您可能需要重新考虑UDP是否是最佳选择。 TCP连接转发是所有NAT设备支持的基本功能,但某些设备可能不支持UDP。