为什么我无法建立 Input/OutputStreams?Java ServerSocket

Why can I not establish the Input/OutputStreams? Java ServerSocket

提问人:hhhhhhhhhhhhhaaaaaaaaaauwu 提问时间:11/16/2023 更新时间:11/16/2023 访问量:56

问:

我有一个 ServerMain 和一个 ClientMain,它们为客户端和服务器线程提供套接字。然后我尝试使用相同的方法制作 ObjectStreams,但出现错误。

ServerMain 错误:

java.net.SocketException: An established connection was aborted by the software in your host machine
    at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:325)
    at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:350)
    at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:803)
    at java.base/java.net.Socket$SocketInputStream.read(Socket.java:966)
    at java.base/java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2875)
    at java.base/java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2891)
    at java.base/java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:3388)
    at java.base/java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:959)
    at java.base/java.io.ObjectInputStream.<init>(ObjectInputStream.java:397)
    at abstractClass.initializeStreams(abstractClass.java:17)
    at MulServerThread.run(MulServerThread.java:12)

abstract类

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public abstract class abstractClass extends Thread {
    protected Socket socket;
    protected ObjectInputStream in;
    protected ObjectOutputStream out;
    protected abstractClass(Socket socket) {
       this.socket = socket;
    }

    protected void initializeStreams() {
        try {
            in = new ObjectInputStream(socket.getInputStream());
            out = new ObjectOutputStream(socket.getOutputStream());

        } catch (IOException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }
    }
}

客户

import java.io.IOException;
import java.net.Socket;

public class ClientMain {

    public static void main(String[] args) {

        try (Socket server = new Socket("localhost", 3141)) {
            Client client = new Client(server);
            client.start();

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
import java.net.Socket;

class Client extends abstractClass {
    Client(Socket socket) {
        super(socket);
    }

    @Override
    public void run() {
        initializeStreams();
    }
}

服务器

import java.io.IOException;
import java.net.ServerSocket;

public class ServerMain {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(3141);
            MulServerThread mulThread = new MulServerThread(serverSocket.accept());
            mulThread.start();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
import java.net.Socket;

class MulServerThread extends abstractClass {

    public MulServerThread(Socket socket) {
        super(socket);
    }

    @Override
    public void run() {
        initializeStreams();
    }
}

它希望我写更多。所以,是的,这是代码的精简版本,因此您不必阅读所有不相关的东西。

Java 套接字 serversocket 对象inputstream

评论

1赞 user207421 11/16/2023
您应该在 .ObjectOutputStreamObjectInputStream
0赞 hhhhhhhhhhhhhaaaaaaaaaauwu 11/16/2023
你是说只是在 initializeStreams() 中切换它们,对吗?这样做后我得到同样的错误。
1赞 user207421 11/16/2023
我没有说它会解决这个问题。它将解决下一个问题;-)
1赞 user207421 11/16/2023
它不会。解决此问题时,如果在两端创建第一个,它将死锁。我保证。幻灯片是否还包含此 try-with-resources 和线程?ObjectInputStream
1赞 user207421 11/16/2023
正是如此。 写入一个可读取的标头,因此必须先创建它。数据输入/输出流不会这样做。new ObjectOutputStream()new ObjectInputStream()

答:

2赞 0x150 11/16/2023 #1

持有套接字的主线程不会等待客户端/服务器退出。它只是启动连接,启动客户端/服务器,然后立即结束 try(){} 块,关闭流。

你应该创建线程,使主线程等待客户端/服务器线程完成,然后再继续,在这一点上,我质疑为什么你甚至要有一个新线程开始。.join()

评论

1赞 0x150 11/16/2023
@user207421这就是我最后说的。>我质疑你为什么会有一个新的线程开始
0赞 hhhhhhhhhhhhhaaaaaaaaaauwu 11/16/2023
我不明白。没有单个主线程,有两个主线程同时运行。serverSocket.accept() 会一直等到客户端执行 initializeStreams();
0赞 user207421 11/16/2023
@hhhhhhhhhhhhhaaaaaaaaaauwu 看一看。它打开 in try-with-resources 块,启动一个线程,然后退出该块,从而自动关闭 .ClientSocketSocket