I have application with Apache HttpComponents 4.4.1 synchronous server , which runs several HTTP "services", for each of them I start HTTP server on different port. When the user decides to stop the service, I shut down HTTP server running on this port with this code:
org.apache.http.impl.bootstrap.HttpServer server;
....
public void stopServer(){
server.shutdown(42, TimeUnit.MICROSECONDS);
}
I have the following problem on Linux: If there are Keep-alive connections opened (there is no request processing), these sockets are not closed. Only ServerSocket is closed:
netstat -aon | grep 58276
TCP 127.0.0.1:50658 127.0.0.1:58276 ESTABLISHED 18012
TCP 127.0.0.1:58276 127.0.0.1:50658 ESTABLISHED 18012
In attempt to start again HTTP server on the same port a BindingException is thrown:
Caused by: java.net.BindException: Address already in use
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.socketBind(PlainSocketImpl.java:521)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:414)
at java.net.ServerSocket.bind(ServerSocket.java:326)
at java.net.ServerSocket.<init>(ServerSocket.java:192)
at javax.net.DefaultServerSocketFactory.createServerSocket(ServerSocketFactory.java:170)
at org.apache.http.impl.bootstrap.HttpServer.start(HttpServer.java:116)
On Windows the behavior is the same , however there is no BindingException and the server starts process requests without any problems.
Turns out to be a bug: https://issues.apache.org/jira/browse/HTTPCORE-420 oleg has already proposed a fix. I will update this when it is released officially.
Your problem is that connection is not closed. The HTTP specification does not specify how long a persistent connection should be kept alive.
From documentation :
Some HTTP servers use a non-standard
Keep-Alive
header to communicate to the client the period of time in seconds they intend to keep the connection alive on the server side.HttpClient
makes use of this information if available. If theKeep-Alive
header is not present in the response,HttpClient
assumes the connection can be kept alive indefinitely.
So they advise to create your KeepAliveStrategy
in order to terminate those connections after certain time:
ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() {
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
// Honor 'keep-alive' header
HeaderElementIterator it = new BasicHeaderElementIterator(
response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (it.hasNext()) {
HeaderElement he = it.nextElement();
String param = he.getName();
String value = he.getValue();
if (value != null && param.equalsIgnoreCase("timeout")) {
try {
return Long.parseLong(value) * 1000;
} catch(NumberFormatException ignore) {
}
}
}
HttpHost target = (HttpHost) context.getAttribute(
HttpClientContext.HTTP_TARGET_HOST);
if ("www.naughty-server.com".equalsIgnoreCase(target.getHostName())) {
// Keep alive for 5 seconds only
return 5 * 1000;
} else {
// otherwise keep alive for 30 seconds
return 30 * 1000;
}
}
};
CloseableHttpClient client = HttpClients.custom()
.setKeepAliveStrategy(myStrategy)
.build();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.