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

Java实现基础RPC服务器时遭遇连接中止错误求助

Java RPC服务器连接中止问题排查与修复

我正在尝试用Java实现一个基础的RPC服务器,客户端发送操作指令后,服务器从数据库获取数据并返回给客户端,但遇到了java.net.SocketException: An established connection was aborted by the software in your host machine错误,相关代码和错误信息如下:

服务器代码

@Override
public void run() {
    String operationType;
    int id;
    while (!socket.isClosed()) {
        try {
            operationType = in.readUTF();
            if (operationType.equals("Take test!")) {
                Future future = pool.submit((Callable) () -> {
                    return studentDAO.getTest(1);
                });
                Object obj = future.get();
                objOut.writeObject(obj);
                pool.shutdown();
            }
            //notifyAllUsers(type);
        } catch (IOException | InterruptedException | ExecutionException ex) {
            System.out.println(ex.getLocalizedMessage());
            close(socket, in, out, objIn, objOut);
            break;
        }
    }
}

客户端代码

public void applyChanges(String operation) {
    new Thread(
            () -> {
                try {
                    if (operation.equals("Take test!")) {
                        out.writeUTF(operation);
                        //objOut.writeInt(1);
                        Test test = (Test) objIn.readObject();
                        System.out.println(test.getTestName());
                    }
                } catch (IOException | ClassNotFoundException ex) {
                    close(socket, in, out, objIn, objOut);
                }
            }, "applyThread"
    ).start();
}

错误信息

run:
Client accepted!
java.net.SocketException: An established connection was aborted by the software in your host machine
    at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:417)
    at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:437)
    at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:823)
    at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1035)
true
    at java.base/java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1901)
    at java.base/java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1810)
    at java.base/java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1304)
    at java.base/java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1249)
    at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1445)
    at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1196)
    at java.base/java.io.ObjectOutputStream.writeFatalException(ObjectOutputStream.java:1617)
Socket closed
    at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:365)
    at server.ClientHandler.run(ClientHandler.java:63)
    at java.base/java.lang.Thread.run(Thread.java:833)

问题根源与修复方案

  1. 线程池过早关闭
    服务器处理完第一个请求就调用pool.shutdown(),这会终止线程池的所有后续任务提交,且可能导致线程池资源异常,间接引发连接中断。应将线程池的关闭逻辑绑定到服务器生命周期(如服务器停止时),而非单次请求后。

  2. 对象输出流未刷新
    服务器写入对象后未调用objOut.flush(),导致数据滞留在缓冲区,客户端长时间等待响应后主动关闭连接,服务器再写入时就会触发连接中止错误。

  3. Test类序列化检查
    确保Test类实现Serializable接口,否则ObjectOutputStream写入时会抛出序列化异常,也会间接导致连接中断。

修复后的服务器代码

@Override
public void run() {
    String operationType;
    int id;
    while (!socket.isClosed()) {
        try {
            operationType = in.readUTF();
            if (operationType.equals("Take test!")) {
                Future future = pool.submit((Callable) () -> {
                    return studentDAO.getTest(1);
                });
                Object obj = future.get();
                objOut.writeObject(obj);
                objOut.flush(); // 强制刷新缓冲区,确保数据发送到客户端
                // 移除此处的pool.shutdown(),线程池在服务器关闭时统一关闭
            }
            //notifyAllUsers(type);
        } catch (IOException | InterruptedException | ExecutionException ex) {
            System.out.println(ex.getLocalizedMessage());
            close(socket, in, out, objIn, objOut);
            break;
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:07:31