【问题标题】:Problem with Server-Client application on KotlinKotlin 上的服务器-客户端应用程序问题
【发布时间】:2020-08-25 23:53:11
【问题描述】:

我有一个简单的客户端-服务器应用程序。客户端写成 Android 项目,服务器是 Gradle Kotlin 项目。这是客户端代码(写成 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))
    }
}

不要关心 Player、Response 和 ResponseType。它们只是数据模型,序列化运行良好。

问题是 Socket 在接受后总是关闭并且 UserConnection 线程没有运行所以我总是看到“玩家 ${user.userName} 的客户端已关闭!!!”

附:我尝试不关闭客户端上的 Socket(关闭 OutputStream 后它会自动关闭)。在客户端不关闭 OutputStream 的情况下,Server 不读取数据(flush 也不工作)

【问题讨论】:

  • 尝试将顶级线程加入主线程?

标签: java multithreading sockets kotlin server


【解决方案1】:

问题出在这一行:

val inputAsString = client.getInputStream().bufferedReader().use { it.readLine() }

它从流中读取所有数据并关闭流,同时 InputStream 关​​闭,套接字自动关闭。 我用这个代替它:

val inputAsString = client.getInputStream().reader().readText()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-03
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    相关资源
    最近更新 更多