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

Socket InputStream读取消息异常,Socket2返回bytesReceived=-1求助

Socket读取返回-1问题分析与解决

核心原因

InputStream.read()返回-1和超时完全是两回事——这说明Socket2的通信对方已经主动关闭了输出流(甚至整个连接),哪怕你觉得连接还活跃,实际对方已经终止了数据发送。

你的代码存在的问题

  • 每次调用都重复设置setSoTimeout(100),完全没必要,建议在Socket初始化时一次性设置好。
  • 当read()返回-1时,直接转字符串会触发StringIndexOutOfBoundsException(因为0到-1的索引范围不合法),而且没做连接断开的判断。
  • 循环等待非空字符串的逻辑,会在对方关闭连接时陷入异常,无法正确处理断开场景。

修复后的代码

public String getMessage(int socketNumber) {
    Socket socket = socketNumber == 2 ? socket2 : socket1;
    byte[] message = new byte[4096];
    int bytesReceived;

    try {
        bytesReceived = socket.getInputStream().read(message);
        // 处理对方关闭连接的情况
        if (bytesReceived == -1) {
            throw new IOException("Socket " + socketNumber + " 已被对方关闭");
        }
        System.out.println("从Socket" + socketNumber + "接收的字节数:" + bytesReceived);
        return new String(message, 0, bytesReceived);
    } catch (SocketTimeoutException e) {
        return "";
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

额外注意事项

  1. 排查Socket2的通信对象:检查你发送给Socket2的消息是否正确,对方是否在响应后主动关闭了输出流,或者对方服务端的逻辑是否存在响应后断开连接的设定。
  2. 优化循环逻辑:循环调用时,除了判断空字符串,还要处理连接断开的异常,避免无限循环:
String response;
try {
    do {
        response = getMessage(2);
    } while (response.isEmpty());
} catch (RuntimeException e) {
    // 处理Socket2断开的情况,比如重新连接或者终止逻辑
    System.err.println("Socket2连接异常:" + e.getMessage());
}
  1. 统一超时配置:在Socket创建完成后(比如socket2 = new Socket(host, port)之后)就调用setSoTimeout(100),不用每次读取都重复设置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 13:45:19