1

Alright, so I've coded what is going to be a simple communication program using a server, really as a test more than anything else, so I know it's missing a lot, but with the following Client class:

public class Client {
    private ObjectInputStream in;
    private ObjectOutputStream out;

    private Socket socket;

    private String server;
    private int port;

    public Client(String ip, int p){
        port = p;
        server = ip;
    }

    public boolean start(){
        try{
            socket = new Socket(server, port);
        }catch(Exception e){
            System.out.println("Exception");
            e.printStackTrace();
            return false;
        }
        try{
            in = new ObjectInputStream(socket.getInputStream());
            out = new ObjectOutputStream(socket.getOutputStream());
            System.out.println("All declared");
        }catch(Exception e){
            System.out.println("Exception");
            e.printStackTrace();
            return false;}
        new LThread().start();
        return true;
    }

    private void sendMessage(Message msg){
        try{
        out.writeObject(msg);
        }catch(Exception e){}
    }

    public static void main(String[] args){
        int portNum = 1500;
        String servers = "localhost";

        Client client = new Client(servers, portNum);

        System.out.println("Client started");

        if(!client.start()){
            System.out.println("Didn't work");
            return;
        }

        System.out.println("Client started again");


        Scanner scan = new Scanner(System.in);

        while(true){
            String i = scan.nextLine();
            client.sendMessage(new Message(2, i));
        }
    }

    class LThread extends Thread{

        public void run(){
            System.out.println("Lthread running");
            while(true){
                try{
                    String message = (String)in.readObject();
                    System.out.println(message);
                }catch(Exception e){
                    e.printStackTrace();}
            }
        }

    }
}

The program simply stops when it reaches the point at which it declares its ObjectInput and Output Streams. The program doesn't exit, it doesn't appear to enter the catch block, and I cannot, at all, figure out what on earth could possibly be causing it. The line "All declared." is never printed, but anything before it is printed. Could anyone please tell me why my program just ceases to function at this point without displaying any errors?

EDIT: I figure that there could be an error somewhere in my Server file, so here's the class:

public class Server {

    private static int uid;

    private ArrayList<ClientThread> clients;
    private int port;
    private boolean cont;

    public Server(int p){
        port = p;
        clients = new ArrayList<ClientThread>();
    }

    public void start(){
        System.out.println("Started");
        cont = true;
        try{
            ServerSocket srvr = new ServerSocket(port);
            System.out.println("Declared socket");
            while(cont){
                Socket sk = srvr.accept();
                System.out.println("Socket accepted");

                if(!cont)break;

                ClientThread t = new ClientThread(sk);
                clients.add(t);
                t.start();
            }
            try{
                srvr.close();
                for(ClientThread t : clients){
                    t.in.close();
                    t.out.close();
                    t.socket.close();
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }catch(Exception e){

            e.printStackTrace();
        }
    }

    private synchronized void broadcast(String msg){
        for(int i=clients.size(); --i >= 0;){
            ClientThread t= clients.get(i);
                if(!t.writeMsg(msg)){
                    clients.remove(i);
                }
        }
    }

    public static void main(String[] args){
        int portNum = 1500;

        Server server = new Server(portNum);
        server.start();
    }

    class ClientThread extends Thread{
        Socket socket;
        ObjectInputStream in;
        ObjectOutputStream out;
        String name;
        int id;
        Message m;

        ClientThread(Socket s){
            id = ++uid;
            socket = s;
            try{
                System.out.println("Before");
                in = new ObjectInputStream(socket.getInputStream());
                out = new ObjectOutputStream(socket.getOutputStream());
                System.out.println("After");
            }catch(Exception e){
                e.printStackTrace();}
        }

        public void run(){
            boolean c = true;
            while(c){
                try{
                    m = (Message)in.readObject();
                    switch(m.getType()){
                    case 2:
                        broadcast(m.getMessage());
                    }
                }catch (Exception e){
                    e.printStackTrace();}
            }
        }

        public boolean writeMsg(String msg){
            if(!socket.isConnected()){
                return false;
            }
            try{
                out.writeObject(msg);
            }catch(Exception e){
                e.printStackTrace();}
            return true;
        }
    }

}

Alright, another edit. So I added those two printlns to the try statement in ClientThread's constructor, and, just like with client, it runs until I try to initialize the streams, and then it just stops. Again, no errors, no anything; it just completely stops in its tracks. I cannot figure out why on earth this happens, but if it means anything, I'm using the Eclipse IDE to run it.

4
  • Just a tip: the two lines above the one that prints "All declared" don't declare anything. Commented Feb 12, 2015 at 2:36
  • How do you know it's not stuck in new Socket(server, port)? Commented Feb 12, 2015 at 2:37
  • @immibis Right, but changing the output to "All assigned." won't really make the code run any better. Commented Feb 12, 2015 at 2:38
  • @immibis I've removed it because I've figured out what I needed to from that line, but I added a line to output something to the console immediately after new Socket(server, port), and it properly printed to the console each time I ran it, so I'm pretty sure that's not the issue. Commented Feb 12, 2015 at 2:39

1 Answer 1

1

I snagged on this the first time I used ObjectInputStream and ObjectOutputStream. At the root cause of your problem is within the constructor ObjectInputStream. The constructor will read from the underlying stream in an attempt to get header information such as the wire format version.

In order to prevent your client and server from infinity waiting for the other to send the information first, you should invert the order of the input and output streams, then flush the output stream explicitly. The following at the construction of the streams in the client and server will fix your problem:

out = new ObjectOutputStream(socket.getOutputStream());
out.flush();
in = new ObjectInputStream(socket.getInputStream());
Sign up to request clarification or add additional context in comments.

Comments

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.