0

It's a messenger application in java. I want to send objects and not just text, I think it's much better. I'm using a ServerSocketChannel and a new Thread for every connected client.
-Same package, same constructor, same serialVersionUID. It just prints out the "before" command, can't read the Client's object.

Part of the server's code:

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

Part of the client's code:

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

(The purpose of my "Error" class is to insert all possible exceptions to database.)

1 Answer 1

1

The main problem is that you're creating an ObjectInputStream in the client: this will block until the ObjectOutputStream in the peer is created, and you're not creating one, at least not in the code you posted. You need to create the ObjectOutputStream and then the ObjectInputStream, immediately, in that order, at both ends.

However you have a further problem. You shouldn't do any I/O whatsoever in the accept loop other than accepting connections. All the object stream creation, login, etc., should be done in the thread created to handle he connection, and NB not in its constructor but in its run() method. Otherwise one rogue or malfunctioning client can block the whole system.

Sign up to request clarification or add additional context in comments.

2 Comments

is it because the constructor for OIS will block until is connected? So when it is instantiated in the client, it blocks before it can write the object to the OOS?
@guido Isn't that exactly what I just said?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.