java - 通过ObjectInputStream接收对象(Java)

标签 java objectinputstream objectoutputstream socketchannel

这是一个用java编写的消息应用程序。我想发送对象而不仅仅是文本,我认为这样要好得多。我为每个连接的客户端使用 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”类的目的是将所有可能的异常插入数据库。)

最佳答案

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

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

关于java - 通过ObjectInputStream接收对象(Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28639708/

相关文章:

java - 可序列化的简单对象 IOException

java - 无法通过 Java 中的 ObjectInputStream 发送对象

java - Liferay 只显示有子项的页面

JavaFX超链接焦点矩形默认样式

java - 确保密码不包含字典单词

java - 读取和到达文件末尾时 ObjectInputStream 出现异常

java - 如何将多个对象写入可序列化文件并在程序再次使用时读取它们?

java - append 到 ObjectOutputStream

java - 如何使用 Java 中的 ObjectInputStream 从文件中读取对象列表?

java - 是否有运行时代理创建库支持保留代理类的注释?