我正在做一个允许两个设备通过套接字连接的应用程序。其中一个创建了一个热点和serversocket
,另一个设备可以加入该热点并连接到serversocket
。
一切正常(实际上在Nougat设备上它会引发网络无法访问的异常,但我通过重试解决了它很好),但 IF数据3g / 4g打开,它根本无法连接,它将被卡住(在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)
编辑: 我知道这里有类似的问题,但没有一个与移动数据相关(至少我没找到),它们只是一般性的。
答案 0 :(得分:2)
当端点(用户)设备想要向远程对等方发送内容时,它通常不知道它们之间的网络。所有设备都有一组网络接口(wifi,蜂窝,蓝牙)和路由表。
大多数接口已经具有由设备(用于wifi)或蜂窝运营商(用于3g / 4g)分配的IP地址。
当要将某些内容发送到IP x.x.x.x
时,设备会查看路由表,尝试查找要使用的接口。如果找不到任何内容(实际上这很可能是场景),则使用默认路由(网关)。
在您的情况下,默认网关可能表示设备应在数据传输打开时通过3g / 4g发送数据。当它关闭时,默认网关被更改为使用wifi,这是该时间点唯一的活动网络接口。
您有四种方法可以解决这个问题。
当你有两个接口(wifi和4g)时,每个接口都会收到它自己的IP。确保使用wifi的IP(通常是192.168.0.0/16
网络)。
添加静态路由,将您的应用流量路由到wifi。不确定它是否可能在一个没有root权限的android上。
获取移动运营商的静态IPv4地址。 IPv4很少,大多数设备都隐藏在NAT / PAT之后,因此无法实现它们之间的直接连接。至少有一方需要另一方知道的全局静态IP地址。
获取移动运营商的IPv6地址。
另请注意,3和4使wifi部分有效使用。