# Android HTTPClient vs HttpUrlConnection vs Socket Verständnisproblem



## newbie2009 (28. Sep 2012)

Hey Leute, 

ich habe ein kleines Verständnisproblem, hinsichtlich der Nutzung des DefaultHttpClients, der HttpUrlConnection und von Sockets. 

Was ich bisher rausgefunden habe: 

Der HttpClient ist depreceated und man sollte auf die HttpUrlConnection ausweichen. In meinem Test war diese auch schneller. Mir stellt sich allerdings die Frage warum das so ist ?  Liegt das vllt daran, dass die HttpUrlConnection versucht eine keep-alive connection by default zu erstellen? Ich weiß  nicht ob es beim HttpClient auch der Fall ist. 


Weiterhin besteht auch die Möglichkeit der Socketnutzung, um TCP basierte Nachrichten auszutauschen. Nun stellt sich mir die Frage warum sollte man dieses Nutzen wenn HttPClient und HttpUrlConnection doch auch auf dem TCP aufsetzen. 

Naja ich hoffe jemand kann ein wenig Licht in meine verwirrte Androidwelt reinbringen, thx im voraus  

mfg newbie


----------



## schlingel (28. Sep 2012)

> Der HttpClient ist depreceated und man sollte auf die HttpUrlConnection ausweichen.


Abenteuerliche Behauptung. Kannst du das auch belegen? In der Doku ist's jedenfalls nicht deprecated gekennzeichnet.



> In meinem Test war diese auch schneller. Mir stellt sich allerdings die Frage warum das so ist?


Weil du alles selbst handlen musst was so üblichen HTTP-Protokolablauf angeht. Also ein redirect wird nicht von der Klasse abgewickelt, Multiform-Uploads sind ein ziemliches Herumärgern, etc. Du bist einfach näher am Metall. 



> Liegt das vllt daran, dass die HttpUrlConnection versucht eine keep-alive connection by default zu erstellen? Ich weiß nicht ob es beim HttpClient auch der Fall ist.


Soweit ich weis schon. Allerdings mit Timeout. Du kannst das aber auch manuell steuern. Siehe Doku dazu. Ob das denn tatsächlich so der Grund ist warum das schneller ist wage ich einmal zu bezweifeln.



> Weiterhin besteht auch die Möglichkeit der Socketnutzung, um TCP basierte Nachrichten auszutauschen. Nun stellt sich mir die Frage warum sollte man dieses Nutzen wenn HttPClient und HttpUrlConnection doch auch auf dem TCP aufsetzen.


Der Vergleich ist mehr wie der Vergleich warum du denn nicht ein Elektroauto mit einem Elektromotor bauen solltest wenn du doch eh Bahn fahren kannst. HTTP ist selbst ein Protokol das auf TCP aufbaut. Da schleppst du also Komplexität mit die du vielleicht nicht brauchst. Gerade was Performance angeht, kann es sein, dass ein eigenes Protokoll etwas bringt.

Da man heutzutage aber meistens über Webservices arbeitet nimmt man diesen kleinen Performancepenaltie gerne in Kauf, da dass das Debuggen auch einfacher macht. Geht ja dann auch mit dem fiddler oder ähnlichen Sniffern.


----------



## newbie2009 (29. Sep 2012)

Hey Danke schon mal für deine Antwort, 



> Abenteuerliche Behauptung. Kannst du das auch belegen? In der Doku ist's jedenfalls nicht deprecated gekennzeichnet.



mit der Kennzeichnung als deprecated hast du recht, allerdings finden sich folgende Hinweise :



```
Since Google has deprecated HttpClient in favor of Java standard HttpURLConnection I created a script to convert a stock release of Apache's HttpClient into an Android library.
```
 (Quelle: java - Apache http client or URLConnection - Stack Overflow )   Und hier allerdings indirekt: 


```
New applications should use HttpURLConnection; it is where we will be spending our energy going forward.
```
(Quelle: Android Developers Blog: Android’s HTTP Clients) 




> Der Vergleich ist mehr wie der Vergleich warum du denn nicht ein Elektroauto mit einem Elektromotor bauen solltest wenn du doch eh Bahn fahren kannst. HTTP ist selbst ein Protokol das auf TCP aufbaut. Da schleppst du also Komplexität mit die du vielleicht nicht brauchst. Gerade was Performance angeht, kann es sein, dass ein eigenes Protokoll etwas bringt.



Da hast du irgendwo natürlich Recht, stand irgendwie aufm Schlauch, trotzdem  hat die Kombination SOAP+TCP bei mir bisher nicht besser abgeschnitten als SOAP und HTTP( Vllt liegt es auch an meinen Messmethoden).
In Android führe ich meine TCP mittels Sockets nach dem folgenden Muster aus : 



```
String path = "/services/soap/";
		    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8"));
		    
		   
		    
		    
		    

       	    
		    writer.write("POST " + path + " HTTP/1.1\r\n");
            writer.write("Host: api.flickr.com\r\n");
            writer.write("Content-Length: " + xml.length() + "\r\n");
            writer.write("Content-Type: text/xml; charset=\"utf-8\"\r\n");
            writer.write("\r\n");

            //Send data
            writer.write(xml);
            writer.flush();
		   

// get response....
```


Wie du siehst, versende ich hier doch auch zahlreiche HttpParameter. Ich weiß, dass die Kombination SOAP+TCP effizienter ist, aber es fällt mir schwer es  irgendwie bildlich vorzustellen, weil ich eben diese Http-Infors mit versende. 



Und zum letzten Punkt:


> Geht ja dann auch mit dem fiddler oder ähnlichen Sniffern.



Ich verwende Fiddler, allerdings zeigt dieser keine TCP-Anfragen an, kannst du vllt noch eine schlanke Variante wie Fiddler empfehlen? Wireshark ist mir zu umfangreich und irgendwie viel zu umständlich.


Vielen Dank im Voraus

mfg newbie


----------



## schlingel (30. Sep 2012)

Naja, in SO kann jeder alles reinschreiben. Das macht's nicht richtiger, dass HttpClient deprecated ist. Den Google Blog kann man allerdings schon ernst nehmen. Ich hab den auch vor einiger Zeit gelesen, als ich meinen Code von HttpClient auf UrlConnection umgestellt habe. (Bei mir war das ganze dann mehr als doppelt so schnell!)

Aber Achtung: Da gibt's so einige Tücken, da vor Android 2.2 die UrlConnection buggy ist. Steht ja auch in dem Blog-Beitrag.

Nein, was besseres bzw. einfacheres als Wireshark kenne ich nicht, da ich mit Wireshark sehr zufrieden bist. Wenn du die IP-Filter einstellst und auf follow TCP Stream klickst, bekommst du den ganzen Inhalt angezeigt.

So, warum ist dein Code performanter als der HttpClient oder die UrlConnection-Klasse?

Ganz einfach: Du hast überhaupt nichts extra, du schreibst einfach Strings in einen Stream und machst dann zu. In den anderen Klassen passiert noch anderes. Fehlerbehandlung, Standardwerte für den HTTP-Header, etc. Das passiert ja bei dir gar nicht. Außerdem ist bei den anderen Varianten mehr als eine Klasse im Spiel, da kommen also noch die Kosten für das Auflösen der Referenzen ins Spiel. (Sind aber sehr gering.)


----------



## newbie2009 (30. Sep 2012)

schlingel hat gesagt.:


> Naja, in SO kann jeder alles reinschreiben. Das macht's nicht richtiger, dass HttpClient deprecated ist. Den Google Blog kann man allerdings schon ernst nehmen. Ich hab den auch vor einiger Zeit gelesen, als ich meinen Code von HttpClient auf UrlConnection umgestellt habe. (Bei mir war das ganze dann mehr als doppelt so schnell!)



Da hast du wiederum Recht, deshalb habe ich zur Sicherheit hier nochmal nachgefragt   Naja bei mir ist die UrlConnection minimal schneller  







schlingel hat gesagt.:


> So, warum ist dein Code performanter als der HttpClient oder die UrlConnection-Klasse?
> 
> Ganz einfach: Du hast überhaupt nichts extra, du schreibst einfach Strings in einen Stream und machst dann zu. In den anderen Klassen passiert noch anderes. Fehlerbehandlung, Standardwerte für den HTTP-Header, etc. Das passiert ja bei dir gar nicht. Außerdem ist bei den anderen Varianten mehr als eine Klasse im Spiel, da kommen also noch die Kosten für das Auflösen der Referenzen ins Spiel. (Sind aber sehr gering.)



Macht Sinn  



schlingel hat gesagt.:


> Nein, was besseres bzw. einfacheres als Wireshark kenne ich nicht, da ich mit Wireshark sehr zufrieden bist. Wenn du die IP-Filter einstellst und auf follow TCP Stream klickst, bekommst du den ganzen Inhalt angezeigt.



Ja habe wieder bisschen rumgespielt und mit den Filtereinstellungen lässt es sich auch damit arbeiten, benutze noch zusätzliche den Microsoft Network Monitor, ist etwas schlanker und einfacher zu bedienen  

Noch eine letzte Frage zum Abschluss: Also ich versuche eine HttpUrlConnection wiederzuverwenden, da ja standardmäßig die Verbindung offen gehalten wird. Wie kann ich mittels Wireshark denn feststellen ob eine Verbindung auch tatsächlich gehalten wird. Meinem Verständnis nach müsste doch dann einfach alle nachfolgenden Anfragen im bestehenden TCP Stream( _wenn ich mittels follow tcp-stream" den stream verfolge_)  auftauchen oder nicht?  Oder bin ich da auf der falschen Spur? 

mfg newbie


----------

