Raghava
Raghava

Reputation: 967

server doesn't receive data from multiple clients (java sockets)

I wrote a simple program where a server should print data sent by multiple clients. But the server receives only partial data. Following are the relevant pieces of the code.

Server:

try {
        serverSocket = new ServerSocket(8888);
    } catch (IOException e) {
        System.err.println("Could not listen on port: 8888");
        System.exit(-1);
    }
 while (listening) {
    Socket clientSocket = serverSocket.accept();
    BufferedReader reader = new BufferedReader(new InputStreamReader(
                            clientSocket.getInputStream()));
        System.out.println(reader.readLine());

        reader.close();
        clientSocket.close();
  }
  serverSocket.close();

Client:

  try {
        socket = new Socket("nimbus", 8888);
        writer = new PrintWriter(socket.getOutputStream(), true);
        localHost = InetAddress.getLocalHost();
    } 
    catch (UnknownHostException e) {} 
    catch (IOException e) {}

    StringBuilder msg1 = new StringBuilder("A: ");
    for(int i=1; i<=3; i++)
        msg1.append(i).append(' ');
    writer.println(localHost.getHostName() + " - " + msg1);

    StringBuilder msg2 = new StringBuilder("B: ");
    for(int i=4; i<=6; i++)
        msg2.append(i).append(' ');
    writer.println(localHost.getHostName() + " - " + msg2);

    StringBuilder msg3 = new StringBuilder("C: ");
    for(int i=7; i<=9; i++)
        msg3.append(i).append(' ');
    writer.println(localHost.getHostName() + " - " + msg3);

    writer.close();
    socket.close();

I get the following output (when run on 3 clients)

nimbus2 - A: 1 2 3 
nimbus3 - A: 1 2 3 
nimbus4 - A: 1 2 3

I don't get the second and third messages. Server keeps waiting. Where am I going wrong?

Edit: In the server code, I tried removing reader.close() and clientSocket.close(). That didn't work either. Another question -- if 3 clients send 3 messages, does it require 9 connections? (this is the reason, I closed the connection in the server code)

Upvotes: 0

Views: 1882

Answers (3)

patheros
patheros

Reputation: 279

You probably want to be delegating the handing of the socket to another thread. I've written up an example that works by passing each incoming socket to an Executor so it can read all the inputs. I use a Executors.newCachedThreadPool() which should grow to be as big as needed. You could also use Executors.newFixedThreadPool(1) if you want it to only be able to handle 1 client at a time.

The only other change I made was I removed the BufferedReader and replaced it with a Scanner. I was having issues with the BufferedReader not returning data. I'm not sure why.

Executor exe = Executors.newCachedThreadPool();
ServerSocket serverSocket = null;
try {
    serverSocket = new ServerSocket(8888);
} catch (IOException e) {
    System.err.println("Could not listen on port: 8888");
    System.exit(-1);
}
while (listening) {
    final Socket clientSocket = serverSocket.accept();

    exe.execute(new Runnable() {

        @Override
        public void run() {
            try {
                Scanner reader = new Scanner(clientSocket.getInputStream());
                while(reader.hasNextLine()){
                    String line = reader.nextLine();
                    System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });

}
serverSocket.close();

Upvotes: 1

MARK
MARK

Reputation: 2362

John is right. you close the client connection by calling clientsocket.close() after reading the message that is why you cannot get the other messages. you should call clientsocket.close() when you have received all the messages

Upvotes: 0

John Ament
John Ament

Reputation: 11723

It looks like you close the connection to the client before they can finish writing/before the server reads all of the messages they sent. I think you need to continue to readline, and potentially not terminate the client's connection after they send you one message.

Upvotes: 0

Related Questions