Groovy中读取Telnet响应遇阻塞问题求助
解决Groovy Telnet通信读取响应卡住的问题
问题根源
- 输出流未刷新:调用
outputStream.write()后,数据可能滞留在本地缓冲区,未真正发送到服务器,导致服务器响应逻辑未触发或响应不完整。 - 读取逻辑阻塞:
BufferedReader.readLine()会持续阻塞,直到读取到换行符或流终止。若服务器返回的响应无换行符结尾,或仍有响应未发送,代码会一直卡在读取步骤。 - 冗余睡眠操作:
Thread.sleep()无法精准匹配服务器响应时机,且会造成不必要的等待。
修正后的代码
import org.apache.commons.net.telnet.TelnetClient import java.net.SocketTimeoutException static void main(String[] args) { def client = new TelnetClient() try { client.connect('servername.dev.net', 9999) def inputStream = client.inputStream def outputStream = client.outputStream def writer = new BufferedWriter(new OutputStreamWriter(outputStream)) // 发送认证命令并立即刷新缓冲区 writer.write("{\"method\":\"authentication\",\"data\":{\"app_key\":\"asdsdfsdfsd\",\"service_id\":1,\"version\":\"4.0.0\"}}") writer.newLine() writer.flush() // 发送获取新闻命令并刷新 writer.write("{\"method\":\"get.news\"}") writer.newLine() writer.flush() // 设置读取超时,避免无限阻塞 client.setSoTimeout(5000) def reader = new BufferedReader(new InputStreamReader(inputStream)) String response try { while ((response = reader.readLine()) != null) { println(response) } } catch (SocketTimeoutException e) { println("读取超时,停止接收响应") } } finally { // 确保连接关闭 if (client.isConnected()) { client.disconnect() } } }
关键改进点
- 强制刷新输出缓冲区:使用
BufferedWriter配合flush(),确保命令立即发送至服务器,避免数据滞留。 - 设置Socket读取超时:通过
client.setSoTimeout()设定超时时间,防止因服务器无响应或响应格式不符导致的无限阻塞。 - 优化资源管理:用
try-finally块保证连接无论是否异常都会关闭,避免资源泄漏。 - 统一换行符处理:用
writer.newLine()生成标准换行符,确保与服务器约定的命令结束格式一致。
内容的提问来源于stack exchange,提问作者Sergey Konotop
相关产品推荐
相关产品推荐

