Search code examples
javabufferedreader

Bufferedreaded ready method losing data


The following method doesn't capture the data sometimes. I believe it is because of the .ready() function.

We have hacked our way through it by doing a sleep, but I don't think it's full proof and seems like a bad hack.

Can you make suggestions on how to fix this method so it works when the request is fully read?

Thanks in advance

/**
     * Parses a client request and calls the appropriate handler
     * @throws Exception
     */
    private void processClientRequest() throws Exception{
            Socket connectedClient = null;
        BufferedReader clientRequest = new BufferedReader(new InputStreamReader(connectedClient.getInputStream()));

        System.out.println(clientRequest);
        String requestString = clientRequest.readLine();

        String header = requestString;

        //Break up request
        StringTokenizer tokenizer = new StringTokenizer(header);

        //Different request parts
        String httpMethod = tokenizer.nextToken();
        String httpQueryString = tokenizer.nextToken();

        //Print client request
        StringBuffer responseBuffer = new StringBuffer();

        //Sleep to bypass weird clientRequest.ready() error
        if (httpMethod.equals("POST")) {
            Thread.sleep(100);
        }

        while (clientRequest.ready()) {
            responseBuffer.append(requestString + " ");
            System.out.println(requestString);

            requestString = clientRequest.readLine();
        }

        //Process GET request
        if (httpMethod.equals("GET")) {
            processGETRequests(httpQueryString, requestString);


        }else if (httpMethod.equals("POST")) {
            processPOSTRequests(responseBuffer, httpQueryString);
        }
    }

Solution

  • When you work with strings you have to always agree on encoding and never use defaults. In your

    // use wathever charset encoding you know is pressent on the socket stream like UTF-8
    new InputStreamReader(socket.getInputStream(), "US-ASCII") 
    

    You don't need to call the ready method, the method readLine() will block untill there is a new line to be read. Your while should be

    while ((requestString = clientRequest.readLine()) != null) {
        // ...
    }