Hi,
Use HttpClient interacts with Tomcat 7.0.21 on Linux,Sometimes HttpClinet
throws Socket Exception that error message is "Connection reset" While reading
response header.Following is Tomcat config and Exception Stack
Tomcat's Connector config:
<Connector port="38080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="3000" redirectPort="38443"
enableLookups="false" acceptCount="4000"
keepAliveTimeout="3000"
URIEncoding="UTF-8"/>
Exception Stack:
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
at
org.apache.commons.httpclient.HttpParser.readRawLine(HttpParser.java:78)
at
org.apache.commons.httpclient.HttpParser.readLine(HttpParser.java:106)
Http Client use MultiThreadedHttpConnectionManager to
manage conntion ,after complete request put connection back to pool rather than
real close.So can reuse in next request. As far as I know the reason why the
client throws connection reset exception should be because of Tomcat close this
connection using Send RST rather than FIN.Because ensure that not set soLinger
option.there must be some other reason.After read this article
http://docs.oracle.com/javase/1.5.0/docs/guide/net/articles/connection_release.html
from oracle,it maybe abortive close,my scenario is similar with the scenario
which the article mentioned:
Say A has sent data to B, but B closes the socket without reading all the
data. In this situation, B's TCP stack knows that some data is effectively lost
and it will forcibly terminate with RST rather than use the orderly FIN
procedure
When HttpClient borrow a connection from ConnectionManager and write
something to this conneciton. In the meanwhile tomcat pepare to close this
connection due to keepalive timeout,so it don't read from this connection and
just close it.
I read NioEndpoint code and find that process time-out after process
selected keys.
Timeout need proccess all key rather than selected keys.During process
timeout,if one socket(channel) receive some data,it will do nothing and just
close it.so the client peer will throw connectionresetException.
Could you please tell me my analysis is correct? I apologize for my poor
English,
Thanks in advance!
// Walk through the collection of ready keys and dispatch
// any active event.
while (iterator != null && iterator.hasNext()) {
SelectionKey sk = iterator.next();
KeyAttachment attachment =
(KeyAttachment)sk.attachment();
// Attachment may be null if another thread has called
// cancelledKey()
if (attachment == null) {
iterator.remove();
} else {
attachment.access();
iterator.remove();
processKey(sk, attachment);
}
}//while
//process timeouts
timeout(keyCount,hasEvents);
Best Regards
Hailei Zhang