1

I need help on my as400 and java connection.

I am experiencing problem on receiving late response during SocketTimeoutExceptions. So what happen is that when i send the first request and response timeout occured, after sending my second request, the response for the first request is received, which creates discrepancy.

Is there a way that after the timeout exception, the response should not cache or should not be received upon next request?

Below is the snippet of my code to connect to the as400 server:

public synchronized static byte[] sendRequestAndGetResponse(byte[] requestBytes) {
    try {
        if(checkHostConnection()){
            LOG.debug("Sending request bytes to Host: {}", Hexifier.toHex(requestBytes));
            IOUtils.write(requestBytes, dos);
            long startTime = System.currentTimeMillis();
            LOG.info("Request sent to host.");

            LOG.info("Waiting on host response");
            byte[] responseLengthBuffer = new byte[4];
            IOUtils.readFully(dis, responseLengthBuffer);

            ByteBuffer bb = ByteBuffer.wrap(responseLengthBuffer);
            int msgLength = bb.getInt();

            byte[] responseRemBytes = new byte[msgLength];
            IOUtils.readFully(dis, responseRemBytes);
            long endTime = System.currentTimeMillis();

            byte[] fullResponseBytes = new byte[responseLengthBuffer.length + responseRemBytes.length];

            System.arraycopy(responseLengthBuffer, 0, fullResponseBytes, 0, responseLengthBuffer.length);
            System.arraycopy(responseRemBytes, 0, fullResponseBytes, responseLengthBuffer.length, responseRemBytes.length);
            LOG.debug("Response from server is received. Time elapsed at {} millis.", (endTime - startTime));
            LOG.debug("Bytes received: {}", Hexifier.toHex(fullResponseBytes));

            return fullResponseBytes;

        } else {
            reconnectToHost();
        }

    } catch (SocketTimeoutException  ste){
        LOG.error("Reading response from socket timeout: {}", ste.getClass().getName());

        try {
            LOG.warn("Waiting for Host reply from its socket timeout.");
            socket.shutdownInput();
            socket.shutdownOutput();

            int hostResponsefromTimeout = dis.read();
            if (hostResponsefromTimeout == -1){
                LOG.debug("Host has responded with -1");

            } else {
                LOG.debug("Host responded with: {}", hostResponsefromTimeout);
            }

        } catch (Exception e){
            LOG.error("Error encountered while trying to validate if Host responded with last timeout.");
           LOG.error(e.getMessage(), e);

        }


        reconnectToHost();

    } catch (EOFException eofe) {
        LOG.debug("An error occurred while reading stream from Host socket connection: {}", eofe.getClass().getName());
        LOG.error(eofe.getMessage(), eofe);

        if (eofe.getMessage() != null && eofe.getMessage().contains("actual: 0")){
            LOG.warn("No bytes were found at stream. Host did not respond.");
        }

        reconnectToHost();

    } catch (SocketException e) {
        LOG.error("An error occurred while attempting to connect to Host: {}", e.getClass().getName());
        LOG.error(e.getMessage(), e);

        if (e.getMessage().contains("Broken pipe")){
            LOG.debug("Connection to Host was lost.");
        }

        reconnectToHost();

    } catch (Exception e) {
        LOG.error(e.getMessage(), e);
        LOG.debug("An error occurred while attempting to connect to Host: {}", e.getClass().getName());
        reconnectToHost();
    }

    return null;
}
alvin
  • 11
  • 3

1 Answers1

0

If you get a SocketTimeoutException on a socket you're otherwise planning to re-use for another request, close it and don't reuse it for another request. Get rid of all that shutdown and read code inside the catch handler and just close the socket. THen you can't possibly get the 'wrong response' for a subsequent request on the same socket.

If you're getting lots of timeouts, your timeout is too short. Typically it should be double the expected service time for the request concerned.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Hello, the method reconnectToHost() after the SocketTimeoutException closes the sockets and creates a new one for another request. That's my initial implementation however delayed response is still experienced. I added the shutdown thing and the read code to make sure i gracefully dropped the connection to the Host: [link] (http://stackoverflow.com/questions/2028620/java-sockets-and-dropped-connections) – alvin Jan 21 '14 at 03:49