简体   繁体   中英

Client freeze on reading object from socket

I'm developing a simple Client-Server application over socket, but I can't get why client freezes when he is reading an object. Server must be capable of dealing with multiple client.

Keeping it simple, my Server looks like:

    ...
    server_thread = new Thread(new Runnable() {
        @Override
        public void run() {
            int p = 0;
            ObjectInputStream in;
            ObjectOutputStream out;
            NetworkOffer message;    

            try (ServerSocket serverSocket = new ServerSocket(port)) {
                // get connections
                LinkedList<Socket> client_sockets = new LinkedList<>();
                while (p++ < partecipants) client_sockets.add(serverSocket.accept());

                // sending welcome object
                for (Socket socket : client_sockets) {
                    out = new ObjectOutputStream(socket.getOutputStream());
                    message = new NetworkOffer();
                    out.writeObject(buyer_offer);
                }
            ...

My Client:

    ...
    client_thread = new Thread(new Runnable() {

        @Override
        public void run() {
            ObjectInputStream in;
            NetworkOffer smessage;
            try {
                Socket ssocket = new Socket("localhost", port);
                in = new ObjectInputStream(ssocket.getInputStream());

                // waiting server message
  ------------->Object o = in.readObject();
                smessage = (NetworkOffer)o;


                System.out.println(smessage.toString());
                ...

EDIT : To make things clearer, this is the protocol I want to implement:

  1. N clients connect to Server
  2. Server send welcome to Clients

  3. Every client makes an offer

  4. Server chooses best offer, and sends a message to each Client with Accept/Reject
  5. If there isn't an acceptable offer goto 3.

Client sticks on Object o = in.readObject(); even if server has already sent his message. No error, nothing. Thread is simply freezed there waiting for something.

What's going on?

The problem is ServerSocket.accept() is a blocking call meaning the server will hang until somebody connects to it. When somebody connects, the server will add that new socket to the client_sockets . If the number of sockets added is less than participants , it will then call accept() again and wait for another connection. It will only enter your for loop when the total number of sockets is equal to participants . You need to spawn a new thread to handle each incoming client socket and allow the server to return immediately to ServerSocket.accept() . Have a look at the Reactor pattern for a good example of how to implement this.

What your code should look like is this:

  1. Server waits for connections.
  2. When client connects, spawn a new thread to handle the connection.
  3. Server returns to waiting for connections.
  4. New thread sends welcome message on socket, adds the socket to the list of client_sockets and waits for the clients offer.
  5. Store the clients offer.
  6. When all offers have been received, compare to find the best.
  7. Send Accept/Reject messages.

As I said before: are you sure that the server have sent the data to the client - there is no buffer flush so it can still be cached.
out.flush() will make sure that buffer is flushed. It will make sense to handle clients separately and send them periodic messages to update them about the status.
It is useful for your server code to handle the client disconnect/connection drop too.

On the side note:

message = new NetworkOffer();
out.writeObject(buyer_offer);

Your code seems to be sending something else that is not present in your example. Is that correct?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM