0

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)

Raghava
  • 947
  • 4
  • 15
  • 29

3 Answers3

1

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();
patheros
  • 279
  • 1
  • 2
  • 11
  • Thank you. Looking at your code, I realized that the problem with my Server code is the missing loop (for reading data). It works fine after adding the loop (and I am using BufferedReader) – Raghava Jan 08 '12 at 18:30
  • I'm glad I could help. If you just use the loop you server will only be able to handle input from one client at a time. If a second client connects while the first one is still sending data the second client will be forced to wait and may timeout. – patheros Jan 08 '12 at 19:52
  • ok, thank you for your inputs :). I would use threads as you suggested. – Raghava Jan 08 '12 at 19:54
0

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.

John Ament
  • 11,595
  • 1
  • 36
  • 45
0

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

MARK
  • 2,302
  • 4
  • 25
  • 44
  • I tried that, I removed clientSocket.close() as well as reader.close(). It doesn't work. Could there be any other reason? – Raghava Jan 08 '12 at 16:49