如果数据打开,则不会创建套接字

Socket won't be created if data on

我正在做一个允许两个设备通过套接字连接的应用程序。其中一个创建一个热点和serversocket,另一个设备可以加入该热点并连接到那个serversocket

一切正常(实际上在 Nougat 设备上它抛出网络无法访问异常,但我通过重试解决了它并且没问题),但是 如果数据 3g/4g 开启,它就赢了't connect ,它会被卡住(在 socket = new Socket(ip,port) 上,一段时间后它会抛出一个 ConnectException _ Connection timed out.

这是错误的完整堆栈:

   java.net.ConnectException: Connection timed out
  W/System.err:     at java.net.PlainSocketImpl.socketConnect(Native Method)
 W/System.err:     at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:334)
  W/System.err:     at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:196)
  W/System.err:     at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:178)
  W/System.err:     at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:356)
  W/System.err:     at java.net.Socket.connect(Socket.java:586)
  W/System.err:     at java.net.Socket.connect(Socket.java:535)
  W/System.err:     at java.net.Socket.<init>(Socket.java:427)
  W/System.err:     at java.net.Socket.<init>(Socket.java:210)

编辑: 我知道这里也有类似的问题,但其中 none 与 移动数据有关 (至少我没有找到),它们只是一般性的。

当端点(用户)设备想要向远程对等点发送内容时,它通常对它们之间的网络一无所知。该设备只有一组网络接口(wifi、蜂窝、蓝牙)和路由table。

大多数接口应该已经有一个由设备(对于 wifi)或蜂窝运营商(对于 3g/4g)分配的 IP 地址。

当要将某些内容发送到 IP x.x.x.x 时,设备会查看路由 table,试图找到要使用的接口。如果什么都找不到(这实际上是最有可能的情况),将使用 默认路由(网关)

在您的情况下,默认网关可能表示设备应在数据传输开启时通过 3g/4g 发送数据。当它关闭时,默认网关更改为使用 wifi,这是当时唯一活动的网络接口。

关于如何克服这个问题,您有四种选择。

  1. 当你有两个接口(wifi 和 4g)时,每个接口都会收到它自己的 IP。确保使用 wifi 的 IP(通常是 192.168.0.0/16 网络)。

  2. 添加静态路由以将您的应用流量路由到 wifi。不确定在没有 root 权限的 android.

  3. 上是否可行
  4. 从您的移动运营商处获取静态 IPv4 地址。 IPv4 很少,大多数设备都隐藏在 NAT/PAT 后面,因此它们之间无法直接连接。至少一方需要另一方已知的全球静态 IP 地址。

  5. 从您的手机运营商处获取 IPv6 地址。

另请注意,3 和 4 使 wifi 部分实际上未被使用。