Apache Http Client prints "[read] I/O error: Read timed out"" Apache Http Client prints "[read] I/O error: Read timed out"" multithreading multithreading

Apache Http Client prints "[read] I/O error: Read timed out""


I'm using httpclient 4.5.2 and in my case, setting the timeouts on a request helped:

HttpPost postRequest = new HttpPost("https://...");postRequest.setHeader(..., ...);RequestConfig requestConfig = RequestConfig.custom()                        .setSocketTimeout(1000)                        .setConnectTimeout(1000)                        .build();postRequest.setConfig(requestConfig);


One of the reasons for having such an error may be that the server follows the policy of closing HTTP connections upon having responded. If that is the case, then this error may be avoided by disabling connection reuse by the client, so there would be no need for the client to verify that the connection is still alive:

httpBuilder.setConnectionReuseStrategy( (response, context) -> false );


The reason is not "multithread", but "http client Pool".

It is not a error, just test the socket stale, and it is good when you want to reuse a socket.See org/apache/httpcomponents/httpcore/4.4.10/httpcore-4.4.10-sources.jar!/org/apache/http/pool/AbstractConnPool.java

for (;;) {    final E leasedEntry = getPoolEntryBlocking(route, state, timeout, tunit, this);    if (validateAfterInactivity > 0)  {        if (leasedEntry.getUpdated() + validateAfterInactivity <= System.currentTimeMillis()) {            if (!validate(leasedEntry)) {                leasedEntry.close();                release(leasedEntry, false);                continue;            }        }    }    entryRef.set(leasedEntry);    done.set(true);    onLease(leasedEntry);    if (callback != null) {        callback.completed(leasedEntry);    }    return leasedEntry;}protected boolean validate(final CPoolEntry entry) {    return !entry.getConnection().isStale();}public boolean isStale() {    if (!isOpen()) {        return true;    }    try {        final int bytesRead = fillInputBuffer(1);        return bytesRead < 0;    } catch (final SocketTimeoutException ex) {        return false;    } catch (final IOException ex) {        return true;    }}

org/apache/httpcomponents/httpcore/4.4.10/httpcore-4.4.10-sources.jar!/org/apache/http/impl/BHttpConnectionBase.java

private int fillInputBuffer(final int timeout) throws IOException {final Socket socket = this.socketHolder.get();final int oldtimeout = socket.getSoTimeout();try {    socket.setSoTimeout(timeout);    return this.inbuffer.fillBuffer();} finally {    socket.setSoTimeout(oldtimeout);}}

Set socket timeout to 1 ms, and read input stream, return these results:

  1. -1 recreate new connection
  2. ">0" reuse connection
  3. timeout exception, reuse connection
  4. IO exception recreate new connection

To avoid this message, just set proper value for validateAfterInactivity , it'sthe min value of client socket timeout, keep-alive time(return by ConnectionKeepAliveStrategy), server connection timeout, and the delay time for idleConnectionMonitor. This does not check connection state, if connect is reset, a new connection will be created.