通过 ObjectInputStream 接收对象 (Java)

Recieving objects through ObjectInputStream (Java)

它是 java 中的 Messenger 应用程序。我想发送对象而不仅仅是文本,我认为这样更好。我正在为每个连接的客户端使用一个 ServerSocketChannel 和一个新线程。
-相同的包,相同的构造函数,相同的 serialVersionUID。 它只是打印出 "before" 命令,无法读取客户端的对象。

部分服务器代码:

    public static void startServer(){
        try{
            ServerSocketChannel ssc=ServerSocketChannel.open();
            ssc.socket().bind(new InetSocketAddress(hostName,portNumber));
            while(isServerRunning()){
                removeLoggedOutClients();
                try{
                    SocketChannel sc=ssc.accept();
                    Socket s=sc.socket();
                    ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
                    Client cli=null;
                    System.out.println("before");
                    cli=(Client)ois.readObject();
                    System.out.println("after");
                    ois.close();
                    if(checkLogin(cli)){
                        System.out.println(cli.getUsername()+" signed in.");
                        cli.setSocket(s);
                        ClientThread ct=new ClientThread(s,cli.getClientID());
                        ct.setDaemon(true);
                        clientThreads.add(ct);
                        ct.start();
                    }
                }
                catch(Exception e){
                    Error err=new Error("Server","void startServer()",2,e.toString());
                }
            }
        }
        catch(Exception e){
            Error err=new Error("Server","void startServer()",1,e.toString());
        }
    }

部分客户代码:

    public static void connectToServer(Client user){
        try{
            SocketChannel sc=SocketChannel.open();
            sc.configureBlocking(true);
            sc.connect(new InetSocketAddress(serverHostName,serverPortNumber));
            Socket s=sc.socket();
            ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
            ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
            oos.writeObject(user);
            oos.flush();
            RecieveThread rt=new RecieveThread(s,ois,user);
            rt.setDaemon(true);
            rt.start();
            setOut(oos);
        }
        catch(Exception e){
            Error err=new Error("Client","connectToServer(Client user)",1,e.toString());
        }
    }

(我的"Error" class的目的是将所有可能的异常插入数据库。)

主要问题是您在客户端中创建了一个 ObjectInputStream:这将阻塞,直到在对等体中创建 ObjectOutputStream,而您至少没有创建一个不在您发布的代码中。您需要立即在两端创建 ObjectOutputStream,然后再创建 ObjectInputStream,

但是你还有一个问题。除了接受连接之外,你不应该在接受循环中做任何 I/O 。所有对象流的创建、登录等,都应该在为处理连接而创建的线程中完成,注意不是在其构造函数中,而是在其 run() 方法中。否则一个流氓或故障客户端可能会阻塞整个系统。