通过ObjectInputStream(Java)接收对象

时间:2015-02-20 23:00:39

标签: java objectinputstream objectoutputstream socketchannel

这是java中的messenger应用程序。我想发送对象而不仅仅是文本,我认为它要好得多。我正在为每个连接的客户端使用ServerSocketChannel和一个新的Thread。
-Same包,相同的构造函数,相同的 serialVersionUID 。 它只是打印出“之前”命令,无法读取客户端的对象。

服务器代码的一部分:

    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());
        }
    }

(我的“错误”类的目的是将所有可能的异常插入数据库。)

1 个答案:

答案 0 :(得分:1)

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

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