You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin实现TCP/IP客户端如何避免永久等待服务端响应

实现方案

要实现“有数据就处理、没数据就先执行其他任务再轮询检查”的逻辑,不需要让readLine()永久阻塞,最简便的测试场景实现方式是给Socket设置读取超时,配合异常捕获完成轮询判断,同时修正原代码的逻辑错误。

核心修改点

  • 给Socket设置soTimeout读取超时参数:比如设置100ms超时,当调用readLine()超过这个时间还没读到数据,就会抛出SocketTimeoutException,不会永久卡住线程
  • 修正原代码的位置错误:原代码把client1.close()写在了子线程代码块外部,会导致子线程刚启动Socket就被主线程关闭,需要把Socket生命周期管理移到子线程内部
  • 增加空值判断:当服务端主动断开连接时,readLine()会返回null,需要做对应判断避免死循环空转
  • 捕获超时异常:触发超时代表当前无可用数据,此时跳转执行其他任务,间隔指定时长后再进入下一轮检查

修改后示例代码

import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.PrintWriter
import java.net.Socket
import java.net.SocketTimeoutException
import kotlin.concurrent.thread

// 原有全局变量保持定义即可
const val SERVER_IP_ADDRESS = "127.0.0.1"
const val SERVER_IP_PORT = 8080
var str_user_text = "测试消息"
var str_rcvd_data: String? = null

fun tcp_client() {
    thread {
        val client1 = Socket(SERVER_IP_ADDRESS, SERVER_IP_PORT).apply {
            // 设置读取超时100ms,可根据实时性要求调整
            soTimeout = 100
        }
        // use函数会自动在代码块结束时关闭Socket,避免资源泄漏
        client1.use { client ->
            val output1 = PrintWriter(client.getOutputStream(), true)
            val input1 = BufferedReader(InputStreamReader(client.inputStream))

            while (true) {
                // 发送逻辑可根据需求调整频率,原逻辑每次循环都发会产生大量重复消息
                output1.println(str_user_text)

                str_rcvd_data = try {
                    input1.readLine()
                } catch (e: SocketTimeoutException) {
                    // 读取超时,代表当前没有新数据到达
                    null
                }

                if (!str_rcvd_data.isNullOrEmpty()) {
                    // 有服务端数据到达,在这里编写数据处理逻辑
                    println("收到服务端返回:$str_rcvd_data")
                } else {
                    // 无可用数据,先执行其他任务
                    println("当前无新数据,执行其他后台逻辑...")
                    // 间隔300ms后再次检查,间隔时长可按需调整
                    Thread.sleep(300)
                }
            }
        }
    }
}

补充说明

  • 上述方案完全满足测试场景需求,实现简单不需要引入额外依赖;如果要做生产环境可用的客户端,不建议用轮询方案,可以改用Java NIO非阻塞通道或者Kotlin协程,实现更低的资源占用和更高的响应效率
  • 超时时间、轮询间隔可以根据实际需求调整:要求响应快就把数值调小,要降低CPU占用就适当增大
  • 原循环内每次都发送消息的逻辑建议优化,避免无意义的重复消息发送,可以改成按固定间隔发送、或者待发送内容更新时再触发发送

内容的提问来源于stack exchange,提问作者garrettb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 04:45:57