Search code examples
javaserverbufferniosocketchannel

How to read from & write to ByteBuffer correctly?


I can't manage to get all data from byteBuffer. I have to methods as follows:

Client side:

public String sendMessage(String msg) {
        buffer = ByteBuffer.wrap(msg.getBytes());
        String response = null;
        try {
            client.write(buffer);
            buffer.clear();
            client.read(buffer);
            response = new String(buffer.array()).trim();
            System.out.println("response=" + response);
            buffer.clear();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }

Server side (There's another method which accepts clients and work with selection keys, I leave it out):

private static void serverResponse(ByteBuffer buffer, SelectionKey key) throws IOException {
        SocketChannel client = (SocketChannel) key.channel();
        client.read(buffer);
        if (new String(buffer.array()).trim().equals("exit")) {
            client.close();
        }
        else {
            ByteBuffer responseBuffer = ByteBuffer.wrap("Example message".getBytes());
            client.write(responseBuffer);
            responseBuffer.clear();
        }
    }

When I call sendMessage() and get data from server within this method, I only receive a small piece of data (e.g. I get only "Examp" from original string "Example message"). And only when I call sendMessage() again I receive the rest of the line (Also separately, I need to call sendMessage() a couple of times). Once I reached the end of the line, it started looping and the next calling sendMessage() returns start of the line. How can I get the full data at once?

I'm pretty sure the question has been answered, but I didn't find the solution myself. Please, help me by giving either the answer or a link to a related question

Note: I noticed that I only get as many characters from buffer as I sent to. So, I believe that the problem is in buffer capacity.


Solution

  • Two issues:

    1. After calling write you should call flush (in both cases).

    2. When you are reading the server's response (on the client side), you are using the same buffer which may not be big enough to hold the whole answer. The buffer size you are using is the size of the initial buffer you created in this line:

       ByteBuffer.wrap(msg.getBytes());
      

    Try to improve it with those suggestions, and see what happen.