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

使用InputStreamReader/OutputStreamWriter实现C/S JSON交互遇阻求助

问题原因与解决方案

这个问题我遇过好多次啦,核心是客户端和服务器互相阻塞形成了死锁,咱们一步步拆解:

为什么会卡住?

  • 首先看客户端代码:你调用out.write(obj.toJSONString())之后,把out.flush()注释掉了。OutputStreamWriter自带缓冲区,默认不会立刻把数据发送到服务器,而是暂时存在客户端本地的缓冲区里。
  • 服务器端的parser.parse(in)方法会一直尝试从输入流读取完整的JSON数据,但因为客户端没把缓冲区里的JSON发过来,服务器就一直卡在这里等待数据。
  • 与此同时,客户端写完数据后立刻执行parser.parse(in),开始等待服务器的响应——两边都在等对方先行动,直接形成了死锁。
  • 而当你移除客户端读取响应的代码时,客户端进程运行结束,JVM会自动关闭Socket的输出流,这时候缓冲区里的JSON数据才会被强制发送到服务器,所以服务器能正常处理请求。

怎么修复?

只需要做两个关键修改:

1. 客户端发送完JSON后强制刷新输出流

必须调用out.flush(),把缓冲区里的JSON数据立刻发送到服务器,这样服务器才能接收到请求并开始处理:

try (OutputStreamWriter out = new OutputStreamWriter(client.getOutputStream(), StandardCharsets.UTF_8)) {
    InputStreamReader in = new InputStreamReader(client.getInputStream(), StandardCharsets.UTF_8);
    out.write(obj.toJSONString());
    out.flush(); // 这行必须加上,把数据推送到服务器

    JSONParser parser = new JSONParser();
    Object response = parser.parse(in);
    JSONObject jsonObj = (JSONObject) response;
    String resp = (String) jsonObj.get("response");
    System.out.println(resp);
}

2. 可选:告知服务器请求已发送完成

有些JSON解析库的parse(Reader)方法会一直读取直到流遇到EOF(结束标记),所以客户端在flush之后,可以关闭Socket的输出方向,告诉服务器“我不会再发数据了”,这样服务器的解析器就能确认JSON已经完整,顺利完成解析:

out.flush();
client.shutdownOutput(); // 关闭输出,保留输入流用于读取响应

服务器端的代码已经做了out.flush()发送响应,这部分是没问题的,不需要修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:59:20