嘿,我使用的是Tomcat 7和HttpClient 4.3.3。我正在尝试使用多个线程连接到我的Servlet,但我经常收到java.net.SocketException: Connection reset
。当我在第一行暂停Servlet的线程时,我仍然在我的客户端上收到异常。
我的问题:这个问题的原因可能与最小活动连接数量太少有关吗?如果没有,请任何人帮我解决这个问题?
try{
// create new httpPost request with url of his class
HttpPost httpPost = new HttpPost( "http://192.168.1.229:8080/test/test" );
// create params and add it to httpPost
List<NameValuePair> paramList = new ArrayList<NameValuePair>();
paramList.add( new BasicNameValuePair( "json_req", format ) );
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity( paramList );
httpPost.setEntity( formEntity );
// execute request and save response
CloseableHttpResponse response = httpclient.execute( httpPost, context );
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
resp = content.available() > 0;
content.close();
response.close();
// return the response
}
catch( Exception e ){
e.printStackTrace();
}
例外:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168)
at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:136)
at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:152)
at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:270)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:140)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:260)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:161)
at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.http.impl.conn.CPoolProxy.invoke(CPoolProxy.java:138)
at $Proxy0.receiveResponseHeader(Unknown Source)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:271)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:254)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at com.pribas.flightcacheservlet.servlet.HTTPThread.run(HTTPThread.java:69)
at java.lang.Thread.run(Thread.java:662)
启动线程的代码:
public static void main( String[] args ) throws Exception{
FileUtil.init();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal( 1000 );
cm.setDefaultMaxPerRoute( 1000 );
cm.setDefaultSocketConfig( SocketConfig.custom().setSoKeepAlive( true ).setSoReuseAddress( true ).setSoTimeout( 3000 ).build() );
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager( cm ).build();
HTTPThread.THREAD_COUNT = 300;
HTTPThread.start = new CountDownLatch( HTTPThread.THREAD_COUNT );
Thread[] threads = new Thread[ HTTPThread.THREAD_COUNT ];
for( int i = 0; i < HTTPThread.THREAD_COUNT; i++ ){
threads[ i ] = new Thread( new HTTPThread( httpClient ) );
}
for( Thread thread : threads ){
thread.start();
}
for( Thread thread : threads ){
thread.join();
}
httpClient.close();
System.out.println( "Average response time: " + calAverage( HTTPThread.times ) + " milliseconds." );
}
答案 0 :(得分:1)
以下是JavaDoc对所述异常的说法:
抛出以指示底层协议中存在错误,例如TCP错误
根据我的个人经验,我遇到过这样的情况,似乎不是其他连接端(服务器)关闭连接而是你的客户端。否则,您会收到另一条消息:Connection reset by peer
这可能由于多种原因而发生,在您的情况下,我猜这与您在工作单元末端没有收集HttpClient
实例的事实有关;因此,请尝试在try
语句的finally块中添加以下行:
try
{
...
}
catch( Exception e )
{
e.printStackTrace();
}
finally
{
httpClient.close(); //close the underlying client.
}
您可能还需要启用SO_KEEPALIVE
以使套接字保持活动状态:
cm.setDefaultSocketConfig(
SocketConfig.custom().setSoKeepAlive(true)
.setSoReuseAddress(true)
.setSoTimeout(3000)
.build());