Frage

Ich habe gelesen, dass HttpURLConnection unterstützt persistente Verbindungen, so dass eine Verbindung für mehrere Anfragen wiederverwendet werden kann. Ich versuchte es, und der einzige Weg, um eine zweite POST war zu senden, indem openconnection ein zweites Mal aufgerufen wird. Ansonsten habe ich eine Illegal ( „Bereits verbunden“); Früher habe ich die folgenden:

try{
URL url = new URL("http://someconection.com");
}
catch(Exception e){}
HttpURLConnection con = (HttpURLConnection) url.openConnection();
//set output, input etc
//send POST
//Receive response
//Read whole response
//close input stream
con.disconnect();//have also tested commenting this out
con = (HttpURLConnection) url.openConnection();
//Send new POST

Die zweite Anforderung wird über die gleiche TCP-Verbindung senden (überprüfte es mit wireshark), aber ich kann nicht verstehen, warum (wenn auch das ist, was ich will), da ich disconnect genannt habe. Ich überprüfte den Quellcode für die HttpURLConnection und die Umsetzung hat die gleichen Ziele eine Keep-Alive-Cache von Verbindungen zu halten. Mein Problem ist, dass ich nicht sehen kann, wie die Verbindung im Cache platziert zurück, nachdem ich die erste Anfrage schicken. Der Trenn schließt die Verbindung und ohne Trenn, noch kann ich nicht sehen, wie die Verbindung im Cache platziert zurück. Ich sah, dass der Cache-Speicher eine run-Methode hat über alle Verbindungen im Leerlauf zu durchlaufen (ich bin nicht sicher, wie es genannt wird), aber ich kann nicht finden, wie die Verbindung wieder in dem Cache gelegt wird. Der einzige Ort, die zu geschehen scheint, ist in der fertigen Methode des Httpclient dies ist jedoch nicht für eine POST mit einer Antwort genannt. Kann mir jemand helfen auf das?

Bearbeiten Mein Interesse ist, was ist die richtige Handhabung eines HttpURLConnection Objekt für TCP-Verbindung Wiederverwendung. Should Eingangs- / Ausgangsstrom geschlossen, gefolgt von einer url.openConnection (); jedes Mal die neue Anforderung (Vermeidung von disconnect ()) senden? Wenn ja, kann ich nicht sehen, wie die Verbindung wiederverwendet wird, wenn ich rufe url.openConnection () zum zweiten Mal, da die Verbindung aus dem Cache für die erste Anforderung entfernt wurde und nicht finden kann, wie es wieder zurückgeführt wird. Ist es möglich, dass die Verbindung nicht zurück in den Keep-Alive-Cache (Bug?) Zurückgegeben wird, aber das Betriebssystem nicht freigegeben hat die TCP-Verbindung noch und auf neue Verbindung, die OS liefern die gepufferte Verbindung (noch nicht erschienen) oder etwas ähnliches? EDIT2 Der einzige Zusammenhang fand ich war von JDK_KeepAlive

  

... wenn die Anwendung ruft close ()   auf der Inputzurück durch   URLConnection.getInputStream (), der   JDK HTTP-Protokoll-Handler wird versuchen,   die Verbindung zu bereinigen, und wenn   erfolgreich, stellen Sie die Verbindung in ein   Verbindungscache für die Wiederverwendung von Zukunft   HTTP-Anfragen.

Aber ich bin nicht sicher, welche Handler dieser ist. sun.net.www.protocol.http.Handler führt keine Zwischenspeicherung als ich sah, Dank!

War es hilfreich?

Lösung

  

Should Eingangs- / Ausgangsstrom geschlossen werden   gefolgt von einer url.openConnection ();   jedes Mal die neue Anfrage senden   (Vermeidung von disconnect ())?

Ja.

  

Wenn ja, kann ich nicht sehen, wie die Verbindung zu sein, ist   wenn ich wiederverwendet nennen   url.openConnection () für das zweite   Zeit, da die Verbindung wurde   aus dem Cache-Speicher für die ersten entfernt   fordern und nicht finden kann, wie es ist   kehrte zurück.

Sie sind verwirrend die HttpURLConnection mit der darunterliegenden Socket und seiner zugrunde liegenden TCP-Verbindung. Sie sind nicht das gleiche. Die HttpURLConnection Instanzen sind GC'd, wird die zugrunde liegende Socket gepoolt, es sei denn, Sie rufen disconnect().

Andere Tipps

Von der javadoc für HttpURLConnection (Hervorhebung von mir):

  

Jede HttpURLConnection Instanz   verwendet, um eine einzelne Anfrage zu machen, aber die   zugrunde liegende Netzwerkverbindung zum   HTTP-Server kann transparent sein   geteilt durch andere Instanzen. Der Aufruf der   close () Verfahren auf der Inputstream oder   Output eines HttpURLConnection   nach einer Anfrage kann Netzwerk frei   Ressourcen, die damit verbunden   Instanz hat aber keinen Einfluss auf irgend   geteilt dauerhafte Verbindung. Berufung   die disconnect () Methode können in der Nähe der   zugrundeliegenden Buchse, wenn eine persistente   Verbindung ist nicht anderweitig genutzt an, dass   Zeit.

Ich fand, dass die Verbindung tatsächlich zwischengespeichert wird, wenn die Input geschlossen ist. Sobald der input geschlossen wurde, wird die zugrunde liegende Verbindung gepuffert. Das HttpURLConnection Objekt ist unbrauchbar für weitere Anfragen obwohl, da das Objekt immer noch als „verbunden“ ist, das heißt seine boolean verbunden wird auf wahr gesetzt und wird nicht gelöscht, sobald die Verbindung wieder in dem Puffer platziert wird. Also jedes Mal, soll eine neue HttpURLConnection für einen neuen POST instanziert werden, aber die zugrunde liegende TCP-Verbindung wird wiederverwendet werden, wenn es nicht abgelaufen ist. So EJP Antwort der war die richtige Beschreibung. Kann das Verhalten, das ich sehe sein (Wiederverwendung der TCP-Verbindung) trotz ausdrücklich disconnect () aufgerufen wurde durch Caching von dem O getan? Ich weiß nicht. Ich hoffe, jemand, der erklären kann, weiß. Danke.

  

Wie kann man "Kraft Verwendung von HTTP1.0" mit der HttpURLConnection von JDK?

Nach dem Abschnitt „Persistent Connections“ die Java 1.5 Führung Unterstützung für HTTP1.1 können Verbindungen der Java-Eigenschaft http.keepAlive ausgeschaltet werden oder über die Verwendung (Standard ist true). Darüber hinaus zeigt die Java-Eigenschaft http.maxConnections die maximale Anzahl von (gleichzeitige) Verbindungen pro Ziel zu einem bestimmten Zeitpunkt am Leben gehalten werden.

Daher ist eine „Kraft Verwendung von HTTP1.0“ für die gesamte Anwendung angewendet werden kann auf einmal durch die Java-Eigenschaft http.keepAlive auf false setzen.

hmmh. Ich kann hier etwas fehle (da dies eine alte Frage ist), aber soweit ich weiß, gibt es 2 bekannte Weisen Schließen der zugrunde liegenden TCP-Verbindung zu erzwingen:

  • Kraft Verwendung von HTTP 1.0 (1.1 eingeführt persistenten Verbindungen) - dies, wie durch die HTTP-Anforderung Linie angezeigt
  • Senden ‚Verbindung‘ Header mit dem Wert ‚schließen‘; dies schließt auch erzwingen.

Der Verzicht auf Ströme werden inaktive TCP-Verbindungen verursachen. Der Antwortstrom sollte vollständig gelesen werden. Ein andere Sache übersah ich anfangs, und übersehen habe zu diesem Thema in den meisten Antworten gesehen wird vergessen, mit dem Fehlerstrom im Fall von Ausnahmen zu behandeln. Code ähnlich wie dieses Fest einen meiner Anwendungen, die nicht war Ressourcen richtig loslassen:

HttpURLConnection connection = (HttpURLConnection)new URL(uri).openConnection();
InputStream stream = null;
BufferedReader reader = null;
try {
        stream = connection.getInputStream();
        reader = new BufferedReader(new InputStreamReader(stream, Charset.forName("UTF-8")));

        // do work on part of the input stream

} catch (IOException e) {

    // read the error stream
    InputStream es = connection.getErrorStream();
    if (es != null) {
        BufferedReader esReader = null;
        esReader = new BufferedReader(new InputStreamReader(es, Charset.forName("UTF-8")));
        while (esReader.ready() && esReader.readLine() != null) {
        }
        if (esReader != null)
            esReader.close();
    }

    // do something with the IOException
} finally {

    // finish reading the input stream if it was not read completely in the try block, then close
    if (reader != null) {
        while (reader.readLine() != null) {
        }
        reader.close();
    }

    // Not sure if this is necessary, closing the buffered reader may close the input stream?
    if (stream != null) {
        stream.close();
    }

    // disconnect
    if (connection != null) {
        connection.disconnect();
    }
}

Die gepufferte Leser sind nicht unbedingt notwendig, wählte ich es, weil mein Anwendungsfall erforderlich, um eine Zeile zu einem Zeitpunkt zu lesen.

Siehe auch: http: // docs .oracle.com / JavaSE / 1.5.0 / docs / guide / net / http-keepalive.html

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top