Android 上的 Indy10。如何强制 TIdUDPClient 尊重 BoundPort 属性 进行 GSM 网络连接?
Indy10 on Android. How can I force TIdUDPClient to respects BoundPort Property for GSM network connection?
在 C++Builder Android 项目中,当设备连接到 WiFi 网络时,TDataModule
上的 TIdUDPClient
按照预期尊重其 BoundPort
:
// BoundPort property is set to 55555...
amcDeviceDM->UDPC->Active = true;
amcDeviceDM->UDPC->Connect();
if(amcDeviceDM->UDPC->Connected())
{
amcDeviceDM->UDPC->SendBuffer(fHost,fPort,Id_IPv4,DataPkt);
}
从 UDP 服务器接收日志中提取:
PeerPort = 55555
如果 WiFi 被禁用,而是设备连接到 GSM 网络(如 Telstra Australia),BoundPort
属性 将被忽略,并且 UDP 服务器接收日志显示:
PeerPort = 37091
如果WiFi重新激活,服务器再次显示:
PeerPort = 55555
有谁知道如何确保始终选择正确的发送端口,即使网络套接字发生变化也是如此?
Indy 没有 WiFi 与 GSM 网络的概念。它只是将套接字绑定到本地 IP/port,而不管它们恰好在 OS/hardware 层关联到什么。您没有看到任何异常引发的事实意味着绑定成功(并且您可以通过在激活套接字后查看 amcDeviceDM->UDPC->Binding->Port
属性 来验证)。
当连接到 GSM 网络时,设备没有 直接 连接到互联网。提供商充当 gateway/proxy 为设备提供互联网访问权限。因此,UDP 服务器将从属于提供商系统的 PeerIP
/PeerPort
对接收数据包,而不是设备(如果 UDP 服务器正在记录PeerIP
)。无论 BoundPort
您决定将 TIdUDPClient
绑定到您设备上的本地,都 对提供商系统使用的端口绑定没有任何影响 ,并且您无法控制那。这很好,因为提供商会为您处理设备 IP/Port 和提供商 IP/Port 之间的链接,因此可以根据需要在它们之间路由数据包。
当连接到 WiFi 时,设备仍然没有直接 连接到互联网。路由器充当网关,为设备提供互联网访问权限。因此,UDP 服务器将从属于路由器而非设备的 PeerIP
/PeerPort
对接收数据包。无论 BoundPort
您决定将 TIdUDPClient
绑定到本地 可能会或可能不会 由路由器保留。当路由器看到需要转发到网络 public(Internet)端的传出 UDP 数据包时,路由器将打开绑定到路由器 public IP 的端口(如果尚未打开),然后从 public IP/Port 发送数据包。 public IP/port 接收到的任何 UDP 数据包将被转发到设备的 IP/Port。打开的端口号通常通常 与原始数据包使用的端口号相同,前提是该端口号当前在路由器上可用,但这并不能保证。因此,即使在 WiFi 网络上,UDP 服务器仍然有可能看到与设备绑定的内容不同的 PeerPort
。这很好,因为路由器将为您处理设备 IP/Port 和路由器 IP/Port 之间的链接,因此可以根据需要在它们之间路由数据包。如果您需要保证路由器的public端口号,您必须在设备开始发送数据包之前在路由器上配置端口映射规则,或者在路由器的静态配置中, 或动态地通过 uPNP.
在 C++Builder Android 项目中,当设备连接到 WiFi 网络时,TDataModule
上的 TIdUDPClient
按照预期尊重其 BoundPort
:
// BoundPort property is set to 55555...
amcDeviceDM->UDPC->Active = true;
amcDeviceDM->UDPC->Connect();
if(amcDeviceDM->UDPC->Connected())
{
amcDeviceDM->UDPC->SendBuffer(fHost,fPort,Id_IPv4,DataPkt);
}
从 UDP 服务器接收日志中提取:
PeerPort = 55555
如果 WiFi 被禁用,而是设备连接到 GSM 网络(如 Telstra Australia),BoundPort
属性 将被忽略,并且 UDP 服务器接收日志显示:
PeerPort = 37091
如果WiFi重新激活,服务器再次显示:
PeerPort = 55555
有谁知道如何确保始终选择正确的发送端口,即使网络套接字发生变化也是如此?
Indy 没有 WiFi 与 GSM 网络的概念。它只是将套接字绑定到本地 IP/port,而不管它们恰好在 OS/hardware 层关联到什么。您没有看到任何异常引发的事实意味着绑定成功(并且您可以通过在激活套接字后查看 amcDeviceDM->UDPC->Binding->Port
属性 来验证)。
当连接到 GSM 网络时,设备没有 直接 连接到互联网。提供商充当 gateway/proxy 为设备提供互联网访问权限。因此,UDP 服务器将从属于提供商系统的 PeerIP
/PeerPort
对接收数据包,而不是设备(如果 UDP 服务器正在记录PeerIP
)。无论 BoundPort
您决定将 TIdUDPClient
绑定到您设备上的本地,都 对提供商系统使用的端口绑定没有任何影响 ,并且您无法控制那。这很好,因为提供商会为您处理设备 IP/Port 和提供商 IP/Port 之间的链接,因此可以根据需要在它们之间路由数据包。
当连接到 WiFi 时,设备仍然没有直接 连接到互联网。路由器充当网关,为设备提供互联网访问权限。因此,UDP 服务器将从属于路由器而非设备的 PeerIP
/PeerPort
对接收数据包。无论 BoundPort
您决定将 TIdUDPClient
绑定到本地 可能会或可能不会 由路由器保留。当路由器看到需要转发到网络 public(Internet)端的传出 UDP 数据包时,路由器将打开绑定到路由器 public IP 的端口(如果尚未打开),然后从 public IP/Port 发送数据包。 public IP/port 接收到的任何 UDP 数据包将被转发到设备的 IP/Port。打开的端口号通常通常 与原始数据包使用的端口号相同,前提是该端口号当前在路由器上可用,但这并不能保证。因此,即使在 WiFi 网络上,UDP 服务器仍然有可能看到与设备绑定的内容不同的 PeerPort
。这很好,因为路由器将为您处理设备 IP/Port 和路由器 IP/Port 之间的链接,因此可以根据需要在它们之间路由数据包。如果您需要保证路由器的public端口号,您必须在设备开始发送数据包之前在路由器上配置端口映射规则,或者在路由器的静态配置中, 或动态地通过 uPNP.