You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by um...@yahoo.com on 2006/11/08 21:46:41 UTC

How to ensure socket reuse on client side?

I am new to HttpCore and using 4.0 Alpha 2 version. I am trying to connect a server and request more than one pages from that server using the same connection. My goal is to reuse socket so that no new socket is opened on the Http client for the subsequent requests to the same server and port.

I get error on the second request. The output / exception stack is as follows:

<< Request: GET / HTTP/1.1
<< Send at: Wed Nov 08 11:57:47 PST 2006
>> Response: HTTP/1.1 200 OK
<< Received: Wed Nov 08 11:57:47 PST 2006
>> Headers Name: Date Value: Wed, 08 Nov 2006 19:57:47 GMT
>> Headers Name: Server Value: Apache/2.2.3 (Unix) mod_ssl/2.2.3 OpenSSL/0.9.7g
>> Headers Name: Last-Modified Value: Wed, 01 Nov 2006 10:45:24 GMT
>> Headers Name: ETag Value: "d4813c-45be-4212d33413900"
>> Headers Name: Accept-Ranges Value: bytes
>> Headers Name: Content-Length Value: 17854
>> Headers Name: Keep-Alive Value: timeout=5, max=100
>> Headers Name: Connection Value: Keep-Alive
>> Headers Name: Content-Type Value: text/html
==============
Connection kept alive...
<< Request: GET /httpcomponents/index.html HTTP/1.1
<< Send at: Wed Nov 08 11:57:48 PST 2006
org.apache.http.ProtocolException: The server jakarta.apache.org failed to respond with a valid HTTP response
	at org.apache.http.impl.DefaultHttpClientConnection.readResponseStatusLine(DefaultHttpClientConnection.java:278)
	at org.apache.http.impl.DefaultHttpClientConnection.receiveResponseHeader(DefaultHttpClientConnection.java:222)
	at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:421)
	at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:204)
	at org.apache.http.examples.ElementalHttpGet.main(ElementalHttpGet.java:118)

If anyone knows the links where I can get more information, that will help. I have modelled my code on the lines of ElementalHttpGet example. The code is as follows:

package org.apache.http.examples;

 

import org.apache.http.ConnectionReuseStrategy;

import org.apache.http.Header;

import org.apache.http.HttpHost;

import org.apache.http.HttpResponse;

import org.apache.http.HttpVersion;

import org.apache.http.Scheme;

import org.apache.http.impl.DefaultConnectionReuseStrategy;

import org.apache.http.impl.DefaultHttpClientConnection;

import org.apache.http.impl.DefaultHttpParams;

import org.apache.http.impl.io.PlainSocketFactory;

import org.apache.http.io.SocketFactory;

import org.apache.http.message.HttpGet;

import org.apache.http.params.HttpParams;

import org.apache.http.params.HttpProtocolParams;

import org.apache.http.protocol.HttpContext;

import org.apache.http.protocol.HttpExecutionContext;

import org.apache.http.protocol.HttpRequestExecutor;

import org.apache.http.protocol.RequestConnControl;

import org.apache.http.protocol.RequestContent;

import org.apache.http.protocol.RequestExpectContinue;

import org.apache.http.protocol.RequestTargetHost;

import org.apache.http.protocol.RequestUserAgent;

 

/**

 * <p>

 * </p>

 * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>

 *

 * @version $Revision: 376458 $

 */

public class ElementalHttpGet {

 

   public static void main(String[] args) throws Exception {

 

      SocketFactory socketfactory = PlainSocketFactory.getSocketFactory();

      Scheme.registerScheme("http", new Scheme("http", socketfactory, 80));

 

      HttpParams params = new DefaultHttpParams(null);

      HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);

      HttpProtocolParams.setContentCharset(params, "UTF-8");

      HttpProtocolParams.setUserAgent(params, "Jakarta-HttpComponents/1.1");

      HttpProtocolParams.setUseExpectContinue(params, true);

           

      HttpHost host = new HttpHost("jakarta.apache.org", 80);

      

      HttpContext context = new HttpExecutionContext(null);

      context.setAttribute(HttpExecutionContext.HTTP_TARGET_HOST, host);

      

      HttpRequestExecutor httpexecutor = new HttpRequestExecutor(context);

      httpexecutor.setParams(params);

      // Required protocol interceptors

      httpexecutor.addInterceptor(new RequestContent());

      httpexecutor.addInterceptor(new RequestTargetHost());

      // Recommended protocol interceptors

      httpexecutor.addInterceptor(new RequestConnControl());

      httpexecutor.addInterceptor(new RequestUserAgent());

      httpexecutor.addInterceptor(new RequestExpectContinue());

 

      DefaultHttpClientConnection conn = new DefaultHttpClientConnection(host);

      ConnectionReuseStrategy connStrategy = new DefaultConnectionReuseStrategy();

      

      try {

       

         String[] targets = {

                              "/",

                              "/httpcomponents/index.html",

                              "/httpcomponents/download.html"         };

         

                          

            for (int i = 0; i < targets.length; i++) {

               

               HttpGet request = new HttpGet(targets[i]);

 

               System.out.println("<< Request: " + request.getRequestLine());

               

               HttpResponse response = httpexecutor.execute(request, conn);

 

               System.out.println(">> Response: " + response.getStatusLine());

               

               Header[] hds = response.getAllHeaders();

               for (Header h: hds){

                  System.out.println(">> Headers Name: " + h.getName() + 

                        " Value: " + h.getValue() );

               }

               

               System.out.println("==============");

               

               if (!connStrategy.keepAlive(response)) {

                  System.out.println("Connection closed.");

                  conn.close();

               } else {

                  conn.flush();

                  System.out.println("Connection kept alive...");

               }

 

            }

                        

      } catch(Exception exp){

         exp.printStackTrace();

      }

      finally {

         conn.close();

      }

   }

 

}


Any help is appreciated.

Thanks.

--
This message was sent on behalf of umesh409@yahoo.com at openSubscriber.com
http://www.opensubscriber.com/messages/httpclient-dev@jakarta.apache.org/topic.html

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpclient-dev-help@jakarta.apache.org


Re: How to ensure socket reuse on client side?

Posted by Ortwin Glück <od...@odi.ch>.
On the HttpComponents front page it says:

"Jakarta HttpComponents project is charged with developing and 
maintaining Commons HttpClient. Commons HttpClient 3 series will be 
maintained until Jakarta HttpClient 4 is deemed stable enough to 
supersede it for use in production."

This text is indeed not very clear. I will add some more text to the 
front page to steer new users into the right direction.

Ortwin

umesh409@yahoo.com wrote:
> Yes, it does fix the problem. Thanks for the help. I remember reading that we need to consume the entire response body (error or no error) so that connection can be used (on the Sun side). It is confirmed here.
> 
> As far the second question about why HttpCore than HttpClient 3.1; I guess it is about the confusion and lack of clarity (Jakarta side does not help much too) - I am unaware which is the latest project which will be maintained in future. My impression is it is HttpCore. I may be wrong here. While I was waiting for a clue on HttpCore issue, I got things tested on HttpClient 3.1 too. I can use any of these two as advised. Socket reuse is my goal (since our application talks to lot of network devices).
> 
> Once again thanks for the help.
> 
> 
> --
> This message was sent on behalf of umesh409@yahoo.com at openSubscriber.com
> http://www.opensubscriber.com/message/httpclient-dev@jakarta.apache.org/5314835.html
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: httpclient-dev-help@jakarta.apache.org
> 

-- 
[web]  http://www.odi.ch/
[blog] http://www.odi.ch/weblog/
[pgp]  key 0x81CF3416
        finger print F2B1 B21F F056 D53E 5D79 A5AF 02BE 70F5 81CF 3416

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpclient-dev-help@jakarta.apache.org


Re: Re: How to ensure socket reuse on client side?

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Thu, 2006-11-09 at 08:07 +0800, umesh409@yahoo.com wrote:
> Yes, it does fix the problem. Thanks for the help. I remember reading that we need to consume the entire response body (error or no error) so that connection can be used (on the Sun side). It is confirmed here.
> 
> As far the second question about why HttpCore than HttpClient 3.1; I guess it is about the confusion and lack of clarity (Jakarta side does not help much too) - I am unaware which is the latest project which will be maintained in future. My impression is it is HttpCore. I may be wrong here. While I was waiting for a clue on HttpCore issue, I got things tested on HttpClient 3.1 too. I can use any of these two as advised. Socket reuse is my goal (since our application talks to lot of network devices).
> 
> Once again thanks for the help.
> 

HttpCore and HttpClient are not mutually exclusive. As of next major
version (4.0) HttpClient will be using HttpCore as its HTTP transport
engine. HttpCore API is still expected to change a lot. The next ALPHA
release will be API incompatible with 4.0-ALPHA2. So, for the time being
you may want to stick to HttpClient 3.x, unless you really want to stay
on the cutting edge and help us shape the HttpCore API.

Cheers

Oleg 

> 
> --
> This message was sent on behalf of umesh409@yahoo.com at openSubscriber.com
> http://www.opensubscriber.com/message/httpclient-dev@jakarta.apache.org/5314835.html
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: httpclient-dev-help@jakarta.apache.org
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpclient-dev-help@jakarta.apache.org


Re: Re: How to ensure socket reuse on client side?

Posted by um...@yahoo.com.
Yes, it does fix the problem. Thanks for the help. I remember reading that we need to consume the entire response body (error or no error) so that connection can be used (on the Sun side). It is confirmed here.

As far the second question about why HttpCore than HttpClient 3.1; I guess it is about the confusion and lack of clarity (Jakarta side does not help much too) - I am unaware which is the latest project which will be maintained in future. My impression is it is HttpCore. I may be wrong here. While I was waiting for a clue on HttpCore issue, I got things tested on HttpClient 3.1 too. I can use any of these two as advised. Socket reuse is my goal (since our application talks to lot of network devices).

Once again thanks for the help.


--
This message was sent on behalf of umesh409@yahoo.com at openSubscriber.com
http://www.opensubscriber.com/message/httpclient-dev@jakarta.apache.org/5314835.html

---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpclient-dev-help@jakarta.apache.org


Re: How to ensure socket reuse on client side?

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Thu, 2006-11-09 at 04:46 +0800, umesh409@yahoo.com wrote:
> I am new to HttpCore and using 4.0 Alpha 2 version. I am trying to connect a server and request more than one pages from that server using the same connection. My goal is to reuse socket so that no new socket is opened on the Http client for the subsequent requests to the same server and port.
> 

...


>                System.out.println(">> Response: " + response.getStatusLine());
> 
>                
> 
>                Header[] hds = response.getAllHeaders();
> 
>                for (Header h: hds){
> 
>                   System.out.println(">> Headers Name: " + h.getName() + 
> 
>                         " Value: " + h.getValue() );
> 
>                }
> 

You should consume the entire response content in order to be able to
reuse the connection. This additional line fixes the problem

---
String stuff = EntityUtils.toString(response.getEntity());
---

Just out of curiosity why are using HttpCore and not HttpClient 3.x?

Oleg 

>                
> 
>                System.out.println("==============");
> 
>                
> 
>                if (!connStrategy.keepAlive(response)) {
> 
>                   System.out.println("Connection closed.");
> 
>                   conn.close();
> 
>                } else {
> 
>                   conn.flush();
> 
>                   System.out.println("Connection kept alive...");
> 
>                }
> 
...


---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpclient-dev-help@jakarta.apache.org