Android: HttpURLConnection does not disable

running netstat on the server:
TILL SEVERAL DAYS AGO . I saw that the connection is ESTABLISHED only about a second and then it will disappear from the list
NOW : it remains as ESTABLISHED for about 10 seconds, then it goes to FIN_WAIT1 and FIN_WAIT2

Android code is the same, server is still the same

Is it possible that some kind of update for Android could change?

I can not explain it.

I inform the code below. urlConnection.disconnect() is being executed, but the connection remains established on the server.

  HttpURLConnection urlConnection = null; System.setProperty("http.keepAlive", "false"); try { URL url = new URL(stringUrl); urlConnection = (HttpURLConnection) url.openConnection(); InputStream instream = new BufferedInputStream(urlConnection.getInputStream()); ... instream.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (urlConnection!=null) { urlConnection.disconnect(); } } 
+6
source share
3 answers

When all the data in the input stream is consumed, the connection is automatically released and added to the connection pool. The main socket connection is not freed, suggesting that the connection will be reused in the near future. It is good practice to call disconnect in the finally block, as it takes care of releasing the connection in case of exceptions .

Here is the implementation of the FixedLengthInputStream reading method :

 @Override public int read(byte[] buffer, int offset, int count) throws IOException { Arrays.checkOffsetAndCount(buffer.length, offset, count); checkNotClosed(); if (bytesRemaining == 0) { return -1; } int read = in.read(buffer, offset, Math.min(count, bytesRemaining)); if (read == -1) { unexpectedEndOfInput(); // the server didn't supply the promised content length throw new IOException("unexpected end of stream"); } bytesRemaining -= read; cacheWrite(buffer, offset, read); if (bytesRemaining == 0) { endOfInput(true); } return read; } 

When the bytesRemaining parameter becomes 0, endOfInput is called , which will use the release method with the true parameter, which will ensure pooling.

 protected final void endOfInput(boolean reuseSocket) throws IOException { if (cacheRequest != null) { cacheBody.close(); } httpEngine.release(reuseSocket); } 

Here is the implementation of the release method. The latter, if verification ensures that the connection must be closed or added to the connection pool for reuse.

 public final void release(boolean reusable) { // If the response body comes from the cache, close it. if (responseBodyIn == cachedResponseBody) { IoUtils.closeQuietly(responseBodyIn); } if (!connectionReleased && connection != null) { connectionReleased = true; // We cannot reuse sockets that have incomplete output. if (requestBodyOut != null && !requestBodyOut.closed) { reusable = false; } // If the headers specify that the connection shouldn't be reused, don't reuse it. if (hasConnectionCloseHeader()) { reusable = false; } if (responseBodyIn instanceof UnknownLengthHttpInputStream) { reusable = false; } if (reusable && responseBodyIn != null) { // We must discard the response body before the connection can be reused. try { Streams.skipAll(responseBodyIn); } catch (IOException e) { reusable = false; } } if (!reusable) { connection.closeSocketAndStreams(); connection = null; } else if (automaticallyReleaseConnectionToPool) { HttpConnectionPool.INSTANCE.recycle(connection); connection = null; } } } 

Note. I previously answered a couple of SO questions related to HttpURLConnection that may help you understand the basic implementation. Here are the links: Link1 and Link2 .

+1
source

How TCP works, when you close a connection, it does not automatically disappear from your socket list.

When you send a completion signal to another part, the protocol starts (morelike procedure), where the first step is your intention to close the connection. You send a signal to another node and which will include the status of FIN_WAIT1 .

When the user received this signal, the next step is to confirm it from the far side. This means that the opposite server sends you another signal, symbolizing that the node is ready to close the connection. This will be the status of FIN_WAIT2 .

Between these two steps, it may happen that the remote node has not answered yet (so you have not been recognized that you want to close the connection). At this time, you will be in an intermediate state called CLOSE_WAIT (resume: after you sent the FIN signal to the remote server and they have not yet answered).

A TIME_WAIT state would mean that you are giving some elegant time to the server before you finally close it in order to receive some packets. You do this because connection abnormalities may occur and the remote server could not receive a disconnect message and send you a packet. Therefore, when this happens, instead of creating a new socket between both nodes, you associate it with the one you have in the TIME_WAIT state, and simply discard this packet, because the sequence number will probably not be ordered.

There are other states that you can see , but according to how you describe it, it seems to me that this is normal for me, if you call the .disconnect() method, the status ESTABLISHED will last. In this case, something does not work properly (it may be due to some overload or non-optimized code, which can make your execution very slow).

0
source

You need to disable open UrlConnection

 HttpURLConnection urlConnection = null; System.setProperty("http.keepAlive", "false"); try { URL url = new URL(stringUrl); urlConnection = (HttpURLConnection) url.openConnection(); InputStream instream = new BufferedInputStream(urlConnection.getInputStream()); ... instream.close(); urlConnection.disconnect(); //HERE } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (urlConnection!=null) { urlConnection.disconnect(); } } 
0
source

Source: https://habr.com/ru/post/971831/


All Articles