一、 异常主信息
failed to connect to /192.168.49.1 (port 8987) from /192.168.237.48 (port 51064) after 10000ms: isConnected failed: ECONNABORTED (Software caused connection abort)
二、 解决思路
1、 首先查看是否是本机原因,
将服务器地址改写成 127.0.0.1 ,端口固定,发现本机可以调通。
// 服务端
serverSocket.bind(InetSocketAddress("127.0.0.1", 8987))
// 客户端
socket.connect(InetSocketAddress("127.0.0.1", port), SOCKET_TIMEOUT)
证明TCP框架没有问题。
2、API 使用检查
发现服务器端 InetSocketAddress 初始化函数调用错误。
// server原代码
serverSocket.bind(InetSocketAddress(8987))
查看InetSocketAddress源码:
public InetSocketAddress(int port) {
// Android-changed: Defaults to IPv6.
// this(InetAddress.anyLocalAddress(), port);
this((InetAddress)null, port);
}
如果没有传递IP地址,默认是使用IPv6,对应的所有相应端口,但是客户端连接时代码为:
// client 原代码
socket.connect(InetSocketAddress("192.168.43.1", 8987), SOCKET_TIMEOUT)
使用IPv4的地址,所以无法连接,应改为:
serverSocket.bind(InetSocketAddress("0.0.0.0", 8987))
发现问题仍然存在,继续找原因。
3、 查看服务端设备和客户端设备 IP地址
命令: adb -s ‘服务端设备' shell ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
41: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 3000
inet 192.168.237.53/23 brd 192.168.237.255 scope global wlan0
valid_lft forever preferred_lft forever
42: p2p0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 3000
inet 192.168.49.1/24 brd 192.168.49.255 scope global p2p0
valid_lft forever preferred_lft forever
根据结果可以看出,p2p0 的ip地址为192.168.49.1/24
,因为我是使用P2P进行连接的,所以关注P2P地址。同时根据错误日志中 ‘connect to’ 消息,
FTClientSocket: java.net.ConnectException: failed to connect to /192.168.49.1 (port 8987) from /192.168.237.48 (port 51064) after 10000ms: isConnected failed: ECONNABORTED (Software caused connection abort)
可以得出结论,我们将要连接的服务器地址是正确的。再查看客户端地址:
命令: adb -s ‘客户端设备' shell ip -4 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
33: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 192.168.49.230/24 brd 192.168.49.255 scope global wlan0
valid_lft forever preferred_lft forever
发现客户端 IP 地址为192.168.49.230/24
, 那么错误日志中 from /192.168.237.48 (port 51064) after 10000ms
的IP地址来自何处,同时发现,如果提前连接好客户端P2P 网络,然后发起Socket连接,竟然没有错误发生。 下面是重新将客户端设备连接到WIFI网络,打印地址:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
33: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 192.168.237.48/23 brd 192.168.237.255 scope global wlan0
valid_lft forever preferred_lft forever
竟然找到了 ‘192.168.237.48’。
三、 结论:
我是在代码调用客户端P2P网络连接后,立刻执行了Client Socket 连接,此时网络切换还没有稳定,客户端设备网络IP地址还没有完全切换成功,所有导致了Socket连接失败,最终将Socket连接放到网络成功监听之后执行,成功。
四、 错误详细信息
08-01 15:07:59.357 7133 7438 D FTClientSocket: [java.net.ConnectException](http://java.net.ConnectException): failed to connect to /192.168.49.1 (port 8987) from /192.168.237.48 (port 51064) after 10000ms: isConnected failed: ECONNABORTED (Software caused connection abort)
08-01 15:07:59.357 7133 7438 D FTClientSocket: at libcore.io.IoBridge.isConnected(IoBridge.java:278)
08-01 15:07:59.357 7133 7438 D FTClientSocket: at libcore.io.IoBridge.connectErrno(IoBridge.java:187)
08-01 15:07:59.357 7133 7438 D FTClientSocket: at libcore.io.IoBridge.connect(IoBridge.java:129)
08-01 15:07:59.357 7133 7438 D FTClientSocket: at [java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:137](http://java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:137))
08-01 15:07:59.357 7133 7438 D FTClientSocket: at [java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:391](http://java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:391))
08-01 15:07:59.357 7133 7438 D FTClientSocket: at [java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:231](http://java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:231))
08-01 15:07:59.357 7133 7438 D FTClientSocket: at [java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:213](http://java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:213))
08-01 15:07:59.357 7133 7438 D FTClientSocket: at [java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436](http://java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436))
08-01 15:07:59.357 7133 7438 D FTClientSocket: at [java.net.Socket.connect(Socket.java:621](http://java.net.Socket.connect(Socket.java:621))
08-01 15:07:59.357 7133 7438 D FTClientSocket: at com.file.p2p.tranfer.FTClientSocket.onHandleIntent(FTClientSocket.kt:45)
08-01 15:07:59.357 7133 7438 D FTClientSocket: at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:76)
08-01 15:07:59.357 7133 7438 D FTClientSocket: at android.os.Handler.dispatchMessage(Handler.java:112)
08-01 15:07:59.357 7133 7438 D FTClientSocket: at android.os.Looper.loop(Looper.java:216)
08-01 15:07:59.357 7133 7438 D FTClientSocket: at android.os.HandlerThread.run(HandlerThread.java:65)
08-01 15:07:59.357 7133 7438 D FTClientSocket: Caused by: android.system.ErrnoException: isConnected failed: ECONNABORTED (Software caused connection abort)
08-01 15:07:59.357 7133 7438 D FTClientSocket: at libcore.io.IoBridge.isConnected(IoBridge.java:267)
08-01 15:07:59.357 7133 7438 D FTClientSocket: ... 13 more