java - Kotlin上的Server-Client应用程序出现问题

标签 java multithreading sockets kotlin server

我有一个简单的客户端服务器应用程序。客户端编写为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()

关于java - Kotlin上的Server-Client应用程序出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61712781/

相关文章:

c# - 如何检查我是否有可以在 StreamReader 上阅读的内容?

java - 将 Jtable 中的多行数据插入数据库

java - 有关 SWT 变量声明顺序的问题

java - 从 ArrayList 获取随机数?

c++ - 单个负载是否与多个存储同步?

c++ - 将套接字传递给线程 C

c# - VB6 Winsock 能够发送非常大的有效载荷

java - 如何使用 httpclient 发送 url post

c++ - 线程安全的 FIFO/队列(多个生产者,一个消费者)

java - Android Java 中的 sleep ()