我有一个简单的客户端-服务器应用程序。客户端编写为Android Project,服务器编写为Gradle Kotlin Project。这是客户端代码(写为AsyncTask):
override fun doInBackground(vararg params: Player){
try {
clientSocket = Socket(host, port)
val writer = PrintWriter(clientSocket.getOutputStream(), true)
writer.write(serializer.toJson(params[0]))
writer.flush()
writer.close()
clientSocket.close()
}catch(e: Exception){
Log.e(TAG, e.message)
}
}
这是服务器代码:
Thread {
while (true) {
val client = serverSocket.accept()
val inputAsString = client.getInputStream().bufferedReader().use { it.readLine() }
val player = serializer.fromJson<Player>(inputAsString)
val connection = UserConnection(client, player, Response(ResponseType.SUCCESS, fetchedText, players))
val thread = Thread(connection)
thread.apply { isDaemon = true }.start()
}
}.start()
和UserConnection类:
class UserConnection(private val connection: Socket, private val player: Player, var response: Response) :
Runnable {
private var connected = true
private val serializer = Gson()
override fun run() {
if(connection.isClosed){
connected = false
println("client of player ${player.userName} is closed!!!")
}
while (connected) {
val writer = PrintWriter(connection.getOutputStream(), true)
println(serializer.toJson(response))
writer.write(serializer.toJson(response))
}
}
不用担心播放器,响应和响应类型。它们只是数据模型,序列化运行良好。
问题是,套接字在接受后始终关闭并且UserConnection线程未运行,所以我总是看到“播放器$ {user.userName}的客户端已关闭!”]
P.S。我尝试不关闭客户端上的Socket(关闭OutputStream后会自动关闭)。如果不关闭客户端上的OutputStream,服务器将无法读取数据(刷新也不起作用)
问题出在这一行:
val inputAsString = client.getInputStream().bufferedReader().use { it.readLine() }
它从流中读取所有数据并关闭流,同时InputStream关闭,套接字自动关闭。代替它,我使用这个:
val inputAsString = client.getInputStream().reader().readText()