2

I am creating a server app which does the following task

  • Accept connection from client
  • Process each client connection to separate thread
  • Receive data from client
  • send data to client

I am able to connect client but not able to receive data from client

Data is being visible in my console only when THAT CLIENT GETS DISCONNECTED..!!!

Code :-

public class ServerListener {

    public static void main(String[] args) {
        new ServerListener().startServer();
    }

    public void startServer() {
        final ExecutorService clientProcessingPool = Executors
                .newFixedThreadPool(10);

        Runnable serverTask = new Runnable() {
            @Override
            public void run() {
                try {
                    ServerSocket serverSocket = new ServerSocket(8000);
                    System.out.println("Waiting for clients to connect...");
                    while (true) {
                        Socket clientSocket = serverSocket.accept();
                        clientProcessingPool
                                .submit(new ClientTask(clientSocket));
                    }
                } catch (IOException e) {
                    System.err.println("Unable to process client request");
                    e.printStackTrace();
                }
            }
        };
        Thread serverThread = new Thread(serverTask);
        serverThread.start();
    }

    private class ClientTask implements Runnable {
        private final Socket clientSocket;

        private ClientTask(Socket clientSocket) {
            this.clientSocket = clientSocket;
        }

        @Override
        public void run() {
            System.out.println("Got a client !");
            try {
            /* Get Data From Client */
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(clientSocket.getInputStream()));
                String clientData = "";
                clientData = reader.readLine();
                System.out.println("Data From Client :" + clientData);

            /* Send Data To Client */

                //Code

                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
12
  • 1
    On the client side, it is a common mistake to not flush() the socket after writing some messages. On the client side, if the outputStream is not flushed, then the data will not be sent until the client ends. Who wrote the client side of the connection? you? Commented Aug 24, 2013 at 12:09
  • 1
    Its a Different application....as of now my TESTING client is Hercules Commented Aug 24, 2013 at 12:15
  • 2
    Change the 'Get data from Client' section to use just the InputStream (no Readers or Buffering): int ch = 0; while ((ch = instream.read()) >= 0) {System.out.println("Got " + ch); } Commented Aug 24, 2013 at 12:27
  • 2
    @linski - I agree with your assessment, but want to caution the OP that he cannot rely on the client sending a message 'abcde' and the server getting that same (complete) message in a single read(byte[]) operation Commented Aug 24, 2013 at 13:24
  • 1
    Code looks fine. Another comment to the OP though, is this sort of complexity in socket communication is the reason why there are protocols put on top of the stream, e.g. tell the server how much data you are going to send so the server knows how much data to expect to receive. HTTP, FTP, SMTP, etc. all have control mechanisms so the remote sides of the sockets know what to expect. Commented Aug 24, 2013 at 13:43

3 Answers 3

7

Problem with your implementation

BufferedReader#readLine:

Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.

In other words, if your client doesn't ever send \nor \r character that method will not end until the IOException gets thrown as a result of disconnect.

Solution

Replace this code:

BufferedReader reader = new BufferedReader(
                    new InputStreamReader(clientSocket.getInputStream()));
String clientData = "";
clientData = reader.readLine();

with:

int red = -1;
byte[] buffer = new byte[5*1024]; // a read buffer of 5KiB
byte[] redData;
StringBuilder clientData = new StringBuilder();
String redDataText;
while ((red = clientSocket.getInputStream().read(buffer)) > -1) {
    redData = new byte[red];
    System.arraycopy(buffer, 0, redData, 0, red);
    redDataText = new String(redData,"UTF-8"); // assumption that client sends data UTF-8 encoded
    System.out.println("message part recieved:" + redDataText); 
    clientData.append(redDataText);
}
System.out.println("Data From Client :" + clientData.toString());

InputStream#read:

Reads some number of bytes from the input stream and stores them into the buffer array b. The number of bytes actually read is returned as an integer. This method blocks until input data is available, end of file is detected, or an exception is thrown.

will read as many bytes as it can at the exact moment of its execution - it is basically buffered reading. Since these are raw bytes, when converting them to String you must know its encoding in order to show them correctly (that's the "UTF-8" part). If the encoding in which your client sends bytes is other, you might need to change it in order to get correct text in console output.

I recommend reading the official tutorial lessons:

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

2 Comments

I have tried this i got output correctly but after append string it doesn't print anything
after search many answer, this i the perfect answer that i found. Thanks you
1

BufferedReader.readLine() will only return when there's an end-of-line or end-of-stream. Make sure the client side is sending a newline character, or use a different way to read the input stream like:

int ch = 0;
while ((ch = instream.read()) >= 0) {
    // do sometyhing with the character off the input stream.
    System.out.println("Got byte " + ch);
}
// will get here when the input stream is closed.

1 Comment

I gets me ASCII Code... I want it as string
0

Might be an issue with your ExecutorService (not?) being called.

Try to subtitute

clientProcessingPool.submit(new ClientTask(clientSocket));

with

BufferedReader reader = new BufferedReader(
    new InputStreamReader(clientSocket.getInputStream()));
String line;
while( (line = reader.readLine()) != null) // just read everything
   System.out.println(line);

And see if you get any output at all.

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.