我正在尝试制作一个尝试连接到服务器的 TCP 客户端。如果无法访问服务器,则必须在固定时间后重试。如果连接丢失,则应尝试重新连接。连接后,它应该能够从服务器读取数据(ASCII 字符串)。这段代码没有按预期工作[应用程序在没有服务器的情况下崩溃]。 我该如何解决? (注意:服务器非常不可靠,不能指望正常断开连接)
package com.thinkalvb.sensorstorm
import android.util.Log
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.net.Socket
import java.net.SocketException
private const val TAG = "Storm_Commander"
class Commander : Runnable {
private lateinit var mTcpSocket: Socket
override fun run() {
val serverAddress = MainActivity.serverAddress
val serverPort = MainActivity.portNumber
while(!Thread.currentThread().isInterrupted) {
try {
Log.d(TAG,"Waiting for Server")
mTcpSocket = Socket(serverAddress, serverPort)
mTcpSocket.soTimeout = 5000
mTcpSocket.keepAlive = true
val receiveBuffer = BufferedReader(InputStreamReader(mTcpSocket.getInputStream(), "UTF-8"))
Log.d(TAG,"Connected to Server")
while (true) {
val command = receiveBuffer.readLine()
if (command != null) {
Log.d(TAG, command)
}
}
} catch (e: SocketException) {
Log.e(TAG, "Socket Error:", e)
} catch (e: IOException) {
Log.e(TAG, "IO Error:", e)
} finally {
mTcpSocket.close()
Log.d(TAG,"Client socket closed")
}
}
}
}
整个项目都在 Github https://github.com/ThinkalVB/SensorStorm
错误:
2021-03-25 21:05:44.201 1865-1865/com.thinkalvb.sensorstorm D/Storm_Location: Location Service created
2021-03-25 21:05:44.204 1865-1865/com.thinkalvb.sensorstorm D/Storm_Acceleration: Acceleration Sensor created
2021-03-25 21:05:44.204 1865-1865/com.thinkalvb.sensorstorm D/Storm_Orientation: Orientation Sensor created
2021-03-25 21:05:44.290 1865-1865/com.thinkalvb.sensorstorm D/Storm_Camera: Camera Service created
2021-03-25 21:05:44.290 1865-1865/com.thinkalvb.sensorstorm D/Storm_Temperature: Temperature Sensor created
2021-03-25 21:05:44.292 1865-1865/com.thinkalvb.sensorstorm D/Storm_MainActivity: Main Activity created
2021-03-25 21:05:48.986 1865-1865/com.thinkalvb.sensorstorm D/Storm_MainActivity: Service starting
2021-03-25 21:05:48.987 1865-1957/com.thinkalvb.sensorstorm D/Storm_Commander: Waiting for Server
2021-03-25 21:07:56.396 1865-1957/com.thinkalvb.sensorstorm E/Storm_Commander: Socket Error:
java.net.ConnectException: failed to connect to /10.0.2.2 (port 1357) from /:: (port 37528): connect failed: ETIMEDOUT (Connection timed out)
at libcore.io.IoBridge.connect(IoBridge.java:137)
at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:137)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
at java.net.Socket.connect(Socket.java:621)
at java.net.Socket.connect(Socket.java:570)
at java.net.Socket.<init>(Socket.java:450)
at java.net.Socket.<init>(Socket.java:250)
at com.thinkalvb.sensorstorm.Commander.run(Commander.kt:20)
at java.lang.Thread.run(Thread.java:764)
Caused by: android.system.ErrnoException: connect failed: ETIMEDOUT (Connection timed out)
at libcore.io.Linux.connect(Native Method)
at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:118)
at libcore.io.IoBridge.connectErrno(IoBridge.java:151)
at libcore.io.IoBridge.connect(IoBridge.java:129)
at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:137)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
at java.net.Socket.connect(Socket.java:621)
at java.net.Socket.connect(Socket.java:570)
at java.net.Socket.<init>(Socket.java:450)
at java.net.Socket.<init>(Socket.java:250)
at com.thinkalvb.sensorstorm.Commander.run(Commander.kt:20)
at java.lang.Thread.run(Thread.java:764)
2021-03-25 21:07:56.405 1865-1865/com.thinkalvb.sensorstorm D/Storm_MainActivity: Service stopping
答案 0 :(得分:0)
为那些寻找一些代码开始的人的临时解决方案。
while(!Thread.currentThread().isInterrupted) {
try {
Log.d(TAG, "Waiting for Server")
mTcpSocket = Socket()
mTcpSocket.connect(serverSocketAddress, 10000)
mTcpSocket.keepAlive = true
mTcpSocket.soTimeout = 15000
if(mTcpSocket.isConnected){
mTCPBufferIncoming = BufferedReader(InputStreamReader(mTcpSocket.getInputStream(), "UTF-8"))
Log.d(TAG, "Connected to Server")
processCommands()
}
mTcpSocket.close()
} catch (e: SocketException) {
Log.e(TAG, "Socket Error:", e)
} catch (e: IOException) {
Log.e(TAG, "IO Error:", e)
} catch (e: Exception) {
Log.e(TAG, "Exception:", e)
}
}
private fun processCommands()
{
var command: String
while (mTCPBufferIncoming.readLine().also { command = it } != null) {
Log.d(TAG, command)
}
}