Inhaltsverzeichnis
Verstehen Sie http persistente Verbindungen (Keep-Alive)
Häufige Missverständnisse und Protokollanalyse
1. Missbrauch der HTTP -Protokollversion
2. Verbindung: Der Effekt des engen Reaktionskopfes
3. Die Bedeutung des serverseitigen Supports
Behandeln Sie HTTP -Antworten und anhaltende Verbindungen korrekt um
Heim Java javaLernprogramm Ein tiefes Verständnis von HTTP -anhaltenden Verbindungen: Richtlinien und Praktiken zum Senden mehrerer Anfragen auf demselben Sockel

Ein tiefes Verständnis von HTTP -anhaltenden Verbindungen: Richtlinien und Praktiken zum Senden mehrerer Anfragen auf demselben Sockel

Sep 21, 2025 pm 01:51 PM

Ein tiefes Verständnis von HTTP -anhaltenden Verbindungen: Richtlinien und Praktiken zum Senden mehrerer Anfragen auf demselben Sockel

In diesem Artikel wird der Mechanismus des Sendens mehrerer HTTP-Anfragen auf demselben TCP-Socket, nämlich die persistierende HTTP-Verbindung (Keep-Alive), eingehend untersucht. Der Artikel verdeutlicht den Unterschied zwischen HTTP/1.x- und HTTP/2-Protokollen, unterstreicht die Bedeutung der serverseitigen Unterstützung für anhaltende Verbindungen und wie die Verbindung korrekt behandelt wird: die Header der Antwort schließen. Durch die Analyse gemeinsamer Fehler und Bereitstellung von Best Practices möchten wir Entwicklern helfen, effiziente und robuste HTTP -Kunden aufzubauen.

Verstehen Sie http persistente Verbindungen (Keep-Alive)

HTTP Persistente Verbindungen, auch als HTTP-Keep-Alive bezeichnet, ermöglichen Clients, mehrere HTTP-Anforderungen und Antworten auf dieselbe TCP-Verbindung zu senden und zu empfangen, ohne eine neue Verbindung für jede Anfrage wiederherzustellen. Dies reduziert den Overhead von TCP -Handshake und langsamer Start erheblich, wodurch die Leistung und Effizienz verbessert werden. In HTTP/1.1 sind anhaltende Verbindungen das Standardverhalten, es sei denn, die Verbindung: Schließung wird explizit angegeben. HTTP/2 geht noch einen Schritt weiter und verarbeitet mehrere Anforderungen und Antworten gleichzeitig auf eine einzelne Verbindung durch Multiplexing.

Das Implementieren des Clients sendet jedoch mehrere Anfragen in denselben Socket, erfordert die korrekte Zusammenarbeit zwischen dem Client und dem Server. Der Client sendet eine Verbindung: Keep-Alive ist nur eine Anfrage, und der Server hat das Recht zu wählen, ob sie akzeptiert werden soll.

Häufige Missverständnisse und Protokollanalyse

Beim Versuch, anhaltende Verbindungen umzusetzen, begegnen Entwickler häufig auf einige Missverständnisse:

1. Missbrauch der HTTP -Protokollversion

Der ursprüngliche Code versucht, eine Anforderung mit der HTTP/2 -Protokollzeichenfolge zu senden:

 "Get /" x "http /2 \ r \ n"

Dies ist ein weit verbreitetes Missverständnis. HTTP/2 und HTTP/1.x sind zwei völlig unterschiedliche Protokolle:

  • HTTP/1.x ist ein textbasiertes Protokoll, und jedes Anforderungs-/Antwortpaar wird normalerweise nacheinander verarbeitet.
  • HTTP/2 ist ein binäres Protokoll, das erweiterte Funktionen wie Multiplexing, Kopfkomprimierung und Serverschub einführt. Es erfordert Protokoll -Upgrades während der TLS -Handshake -Phase durch Anwendungsschichtprotokollverhandlung (ALPN), anstatt einfach HTTP/2 in der Anforderungszeile zu deklarieren. Das Ersetzen von HTTP/1.1 durch HTTP/2 erlaubt dem HTTP/1.x -Server nicht, HTTP/2 -Anforderungen zu verstehen, sondern führt stattdessen zu Protokollfehlern. Für HTTP/1.x -Server sollten immer HTTP/1.1 oder HTTP/1.0 verwendet werden.

2. Verbindung: Der Effekt des engen Reaktionskopfes

Wenn der Server eine Verbindung enthält: Schließen Sie den Antwortheader, weist er den Client explizit an, die TCP -Verbindung nach Erhalt der aktuellen Antwort zu schließen. Dies bedeutet, dass die Entscheidung des Servers auch dann endgültig ist, wenn der Client eine Verbindung sendet: In der Anfrage in der Anfrage aufbewahrt.

Im Beispielausgang:

 HTTP/1.1 200 OK
Inhaltslänge: 2
Inhaltstyp: Text/Ebene
Verbindung: Schließen
Akzeptieren von Ranges: Keine

Der Server gibt explizit die Verbindung zurück: Schließen Sie, also schließt er nach dem Senden der aktuellen Reaktionsbehörde die Socket -Verbindung. Nach dem Lesen aller Daten kehrt der Leser.readline () des Clients NULL zurück, da die Verbindung geschlossen ist, wodurch die Schleife endet und nachfolgende Anfragen nicht auf demselben Sockel gesendet werden können.

3. Die Bedeutung des serverseitigen Supports

Der Kern der Implementierung persistierter Verbindungen ist, ob der Server dies unterstützt und ermöglicht. Insbesondere auf ressourcenbezogenen Geräten wie ESP32-Mikrocontrollern entscheiden sich ihr HTTP-Stack möglicherweise dafür, anhaltende Verbindungen nicht zu implementieren oder zu aktivieren, um Ressourcen zu vereinfachen und zu sparen. In diesem Fall kann der Server darauf bestehen, die Verbindung zu schließen, unabhängig davon, wie der Client die Verbindung anfordert: Keep-Alive.

Behandeln Sie HTTP -Antworten und anhaltende Verbindungen korrekt um

Um mehrere HTTP -Anforderungen in derselben Socket korrekt zu behandeln, benötigt der Client:

  1. Senden Sie den richtigen HTTP/1.1 -Anforderungsheader : Stellen Sie sicher, dass die Anforderungszeile HTTP/1.1 verwendet und den Host -Header enthält. Wenn Sie eine anhaltende Verbindung erwarten, können Sie explizit die Verbindung senden: Keep-Alive, dies ist jedoch nicht obligatorisch, da HTTP/1.1 standardmäßig eine anhaltende Verbindung ist.

     String request = string.format (
        "Get/%s http/1.1 \ r \ n" // mit http/1.1
          "Host: %s \ r \ n"
          "Verbindung: Keep-Alive \ r \ n" // fordern Sie explizit eine persistente Verbindung an. "\ R \ n",
        x, Hostname
    );
    output.write (Anfrage);
    output.flush ();
  2. Richtiges Lesen von HTTP -Antwort : Dies ist der kritischste Schritt. Die HTTP -Antwort besteht aus einer Statuslinie, einem Antwortheader und einem Antwortkörper. Beim Lesen der Antwort können Sie nicht einfach durch Readline () durchlaufen, bis Sie NULL zurückgeben, da dies blockiert wird, bis die Verbindung geschlossen ist. Der richtige Weg, dies zu tun, ist:

    • Lesen Sie die Antwort -Header -Linie nach Zeile : Bis eine leere Zeile (\ r \ n) auftritt, endet der Header.
    • Reaktionsüberwachung an Parsen : Insbesondere Inhaltslänge und Verbindungsheader.
      • Wenn die Inhaltslänge besteht, wird der Antwortkörper der angegebenen Anzahl von Bytes gelesen.
      • Wenn die Übertragungskodierung: Chunked existiert, wird der Antwortkörper von der Chunking-Codierungsregel gelesen.
      • Verbindungsheader auflösen: Wenn der Server auf die Verbindung reagiert: Schließen, sollte der Client den Socket nach dem Lesen der aktuellen Antwort schließen. Wenn Sie auf Verbindung antworten: Keep-Alive (oder nicht angegeben, http/1.1 Standard), können Sie versuchen, die nächste Anfrage zu senden.

Beispiel: Eine robustere reaktionsschnelle Leselogik (vereinfachte Version, nicht vollständig für alle HTTP -Details analysiert)

Der folgende Code -Snippet zeigt, wie eine Antwort liest und entscheidet, ob sie basierend auf dem Verbindungsheader fortgesetzt werden sollen:

 import Java.io.*;
importieren java.net.socket;
importieren java.net.url;
import Java.util.hashMap;
import Java.util.map;

öffentliche Klasse httpclientRobust {

    private Socket Socket;
    private Druckschreiberausgabe;
    privater BufferedReader -Leser;
    private String -Hostname;
    private boolean keepalive = true; // Angenommen, dass zunächst erwartet wird, dass die Verbindung public httpclientRobust () IOException {auswirkt {
        URL URL = neue URL ("http://192.168.178.56"); // Ersetzen Sie durch Ihre ESP32 IP
        hostname = url.gethost ();
        int port = 80;

        Socket = neuer Socket (Hostname, Port);
        output = neuer printwriter (socket.getOutputStream ());
        Reader = neuer BufferedReader (neuer InputStreamReader (Socket.getInputStream ()));
    }

    public void sendandreceive (String Path) löst IOException, InterruptedException {aus
        if (! Keepalive) {
            System.out.println ("Verbindung mit Server geschlossen. In diesem Socket kann nicht mehr Anfragen gesendet werden.");
            zurückkehren;
        }

        String request = string.format (
            "Get /%s http /1.1 \ r \ n"
              "Host: %s \ r \ n"
              "Verbindung: Keep-Alive \ r \ n" // Die Client fordert die Verbindung "\ r \ n" an, um die Verbindung zu halten.
            Pfad, Hostname
        );

        System.out.println ("--- Senden von Anfrage ---");
        System.out.println (Anfrage);
        output.write (Anfrage);
        output.flush ();

        System.out.println ("--- Empfangsantwort ---");
        Karte <string string> Headers = New HashMap  ();
        Stringlinie;
        int contentLength = -1;

        // Lesen Sie die Statuszeilenzeile = reader.readline ();
        if (line == null) {
            System.out.println ("Server geschlossene Verbindung vorzeitig.");
            keepalive = false;
            zurückkehren;
        }
        System.out.println (Linie); // Statuszeile drucken // Antwort -Header lesen und analysieren (((line = reader.readline ())!
            System.out.println (Linie);
            int colonIndex = line.indexof (':');
            if (colonIndex> 0) {
                String headername = line.substring (0, colonIndex) .trim ();
                String Headervalue = line.substring (colonIndex 1) .trim ();
                Header.put (Headername.TolowerCase (), Headervalue);
            }
        }

        // Verbindungsheader überprüfen, wenn ("schließen" .EqualSignoreCase (Headers.get ("Verbindung"))) {
            keepalive = false;
            System.out.println ("Server, der zur Schließung der Verbindung angefordert wird");
        }

        // Inhaltslänge überprüfen
        if (Headers.ContainsKey ("Inhaltslänge")) {
            versuchen {
                contentLength = integer.parseInt (Headers.get ("Inhaltslänge"));
                System.out.println ("Content-Length:" ContentLength);
                // Lesen Sie den Antwortkörper char [] buffer = new char [contentLength];
                int bytesRead = 0;
                while (byteSread <contentlength int result="reader.read" bytesread contentlength if system.out.println verbindung geschlossen bevor vollst inhalte gelesen werden. keepalive="false;" brechen neue string catch e system.err.println header inhaltlicher l anders wenn es keine inhaltsl gibt und nicht untergebracht ist der server explizit heruntergefahren wird geschlossen. dann lesen sie bis die ist. dies gilt in anhaltenden verbindungen. das ende sollte anhand oder beurteilt f den fall dem sendet: schlie diesem beispiel k weiter null verwendet inhaltliche angegeben. eof. stringbuilder responsebody="new" while reader.readline> 0) {
                System.out.println ("Reaktionskörper:" ResponseBody.ToString (). Trim ());
            }
        }

        if (! Keepalive) {
            schließen();
        }
    }

    public void close () wirft ioException {aus
        if (Socket! = NULL &&! Socket.isclosed ()) {
            socket.close ();
            System.out.println ("Socket geschlossen.");
        }
    }

    public static void main (String [] args) löst IoException, InterruptedException {aus
        HttpclientRobust client = null;
        versuchen {
            client = new httpclientRobust ();
            für (int i = 1; i <p> <strong>Anmerkungen:</strong></p>
<ul>
<li> Reader.Read (Buffer, ByteSread, ContentLength - ByteSread) Im obigen Beispiel ist die richtige Art und Weise, einen Antwortkörper mit fester Länge zu lesen.</li>
<li> Reader.Ready () ist möglicherweise nicht zuverlässig genug, wenn das Antwortkörper gelesen wird, da die Daten möglicherweise weiterhin im Transport sind, aber den Puffer noch nicht erreicht haben. Robustere HTTP-Clients benötigen eine komplexere Logik, um verschiedene Übertragungsbeschreibungen (z. B. Taktübertragungen) und Zeitüberschreitungen zu verarbeiten.</li>
<li> Wenn der Server auf die Verbindung reagiert: Schließen, wird das Keepalive -Flag auf false festgelegt und nachfolgende Anfragen werden nicht gesendet.</li>
</ul>
<h3> Zusammenfassung und Best Practices</h3>
<ol>
<li><p> <strong>Verständnis von Protokollunterschieden</strong> : HTTP/1.x und HTTP/2 sind unterschiedliche Protokolle. Verwechseln Sie ihre Verwendung nicht. Für die meisten einfachen Webdienste ist HTTP/1.1 ausreichend und seine anhaltende Verbindung ist das Standardverhalten.</p></li>
<li><p> <strong>Respektieren Sie die Serverabsicht</strong> : Client-Anfragen Anfragen Verbindung: Keep-Alive nur ein Vorschlag, und der Verbindungsantwort-Header des Servers (insbesondere die Verbindung: Schließung) hat die endgültige Entscheidung. Überprüfen Sie immer den Antwortheader des Servers.</p></li>
<li><p> <strong>Analysieren Sie die Antwort korrekt</strong> : Verlassen Sie sich nicht auf die READLINE () Schleife (), bis sie Null zurückgibt, um das Ende der Antwort zu bestimmen, was für anhaltende Verbindungen falsch ist. Inhaltslänge oder Übertragungskodierung muss analysiert werden, um die Grenzen des Reaktionskörpers zu bestimmen.</p></li>
<li><p> <strong>Berücksichtigen Sie Serverfunktionen</strong> : Insbesondere für eingebettete Geräte (wie ESP32) kann der HTTP -Stack nur begrenzte Funktionen aufweisen. Wenn der Server keine anhaltenden Verbindungen unterstützt, sollte der Client bereit sein, für jede Anfrage eine neue Verbindung herzustellen.</p></li>
<li>
<p> <strong>Use mature HTTP client libraries</strong> : For complex HTTP communication, it is highly recommended to use Java built-in java.net.HttpURLConnection or third-party libraries such as Apache HttpClient, OkHttp, etc. These libraries have dealt with the complexity of the HTTP protocol, including persistent connections, redirection, authentication, SSL/TLS, timeouts, usw., die Entwicklungsarbeit stark vereinfacht. Zum Beispiel:</p>
<pre class="brush:php;toolbar:false"> importieren java.net.uri;
importieren java.net.http.httpclient;
importieren java.net.http.httprequest;
importieren java.net.http.httpresponse;
java.time.duration importieren;

öffentliche Klasse ModernhttpclientExample {
    public static void main (String [] args) löst Ausnahme {aus {
        Httpclient client = httpclient.newbuilder ()
                .version (httpclient.version.http_1_1) // Verwenden Sie eindeutig http/1.1
                .ConnectTimeout (Dauer. Ofseconds (10))
                .bauen();

        für (int i = 1; i  response = client.send (request, httPesponse.bodyHandlers.ofstring ());

            System.out.println ("Anfrage" i "to /" Path);
            System.out.println ("Statuscode:" response.statusCode ());
            System.out.println ("Antwortkörper:" Response.body ());
            System.out.println ("Verbindungsheader:" response.Headerers (). FirstValue ("Verbindung"). Orelse ("n/a"));

            // Die Httpclient -Bibliothek kümmert sich automatisch anhaltende Verbindungen. Wenn der Server die Verbindung zurückgibt: Schließen, schließt er die aktuelle Verbindung und stellt beim nächsten Anfragen eine neue Verbindung her.
            Thread.sleep (1000);
        }
    }
}

Durch die Befolgung dieser Prinzipien können Entwickler HTTP-Verbindungen effektiver verwalten und Hochleistungs- und zuverlässige Webanwendungen erstellen.

Das obige ist der detaillierte Inhalt vonEin tiefes Verständnis von HTTP -anhaltenden Verbindungen: Richtlinien und Praktiken zum Senden mehrerer Anfragen auf demselben Sockel. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Stock Market GPT

Stock Market GPT

KI-gestützte Anlageforschung für intelligentere Entscheidungen

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

So erstellen Sie eine Datei in Java So erstellen Sie eine Datei in Java Sep 21, 2025 am 03:54 AM

Usefile

Wie füge ich dem Klassenpfad eine JAR -Datei in Java hinzu? Wie füge ich dem Klassenpfad eine JAR -Datei in Java hinzu? Sep 21, 2025 am 05:09 AM

Verwenden Sie den Parameter -cp, um das JAR zum Klassenpfad hinzuzufügen, damit das JVM seine internen Klassen und Ressourcen laden kann, wie z.

Wie implementiere ich eine Schnittstelle in Java? Wie implementiere ich eine Schnittstelle in Java? Sep 18, 2025 am 05:31 AM

Verwenden Sie das Keyword implementiert die Benutzeroberfläche. Die Klasse muss spezifische Implementierungen aller Methoden in der Schnittstelle bereitstellen. Es unterstützt mehrere Schnittstellen und wird von Commas getrennt, um sicherzustellen, dass die Methoden öffentlich sind. Die Standard- und statischen Methoden nach Java 8 müssen nicht umschreiben.

Wie lese ich eine Eigenschaftendatei in Java? Wie lese ich eine Eigenschaftendatei in Java? Sep 16, 2025 am 05:01 AM

Verwenden Sie die Eigenschaftenklasse, um Java -Konfigurationsdateien einfach zu lesen. 1. Konfiguration. Properties in das Ressourcenverzeichnis, laden Sie es über getClassLoader (). GetResourceAsStream () und rufen Sie die Methode load () auf, um die Datenbankkonfiguration zu lesen. 2. Wenn sich die Datei in einem externen Pfad befindet, verwenden Sie sie mit FileInputStream, um sie zu laden. 3. Verwenden Sie GetProperty (Schlüssel, StandardValue), um fehlende Tasten zu verarbeiten und Standardwerte bereitzustellen, um die Ausnahmeregelung und Eingabeüberprüfung sicherzustellen.

Erstellen erweiterbarer Anwendungen mit der Java Service Provider Interface (SPI) Erstellen erweiterbarer Anwendungen mit der Java Service Provider Interface (SPI) Sep 21, 2025 am 03:50 AM

Javaspi ist ein integrierter Service-Erkennungsmechanismus in JDK und implementiert die dynamische Ausdehnung der interface-orientierten Dynamik durch Serviceloader. 1. Definieren Sie die Serviceschnittstelle und erstellen Sie eine Datei mit dem vollständigen Namen der Schnittstelle unter meta-inf/diensten/und schreiben Sie den vollständig qualifizierten Namen der Implementierungsklasse. 2. Verwenden Sie Serviceloader.load (), um die Implementierungsklasse zu laden, und das JVM wird die Konfiguration automatisch lesen und sie instanziieren. 3. Der Schnittstellenvertrag sollte während des Entwurfs, der Unterstützung von Priorität und bedingten Belastung geklärt und die Standardimplementierung bereitstellen. 4. Die Anwendungsszenarien umfassen Mehrzahler-Kanalzugriff und Plug-in-Überprüfung. 5. Achten Sie auf Leistung, Klassenpfad, Ausnahme -Isolation, Thread -Sicherheit und Versionskompatibilität; 6. In Java9 kann die Bereitstellung in Kombination mit Modulsystemen verwendet werden.

Ein tiefes Verständnis von HTTP -anhaltenden Verbindungen: Richtlinien und Praktiken zum Senden mehrerer Anfragen auf demselben Sockel Ein tiefes Verständnis von HTTP -anhaltenden Verbindungen: Richtlinien und Praktiken zum Senden mehrerer Anfragen auf demselben Sockel Sep 21, 2025 pm 01:51 PM

In diesem Artikel wird der Mechanismus des Sendens mehrerer HTTP-Anfragen auf demselben TCP-Socket, nämlich die persistierende HTTP-Verbindung (Keep-Alive), eingehend untersucht. Der Artikel verdeutlicht den Unterschied zwischen HTTP/1.x- und HTTP/2-Protokollen, unterstreicht die Bedeutung der serverseitigen Unterstützung für anhaltende Verbindungen und wie die Verbindung korrekt behandelt wird: die Header der Antwort schließen. Durch die Analyse gemeinsamer Fehler und Bereitstellung von Best Practices möchten wir Entwicklern helfen, effiziente und robuste HTTP -Kunden aufzubauen.

Java -Tutorial: Wie man eine verschachtelte Arraylist überflätt und ihre Elemente in ein Array füllt Java -Tutorial: Wie man eine verschachtelte Arraylist überflätt und ihre Elemente in ein Array füllt Sep 18, 2025 am 07:24 AM

In diesem Tutorial wird beschrieben, wie verschachtelte Arraylisten effizient verarbeitet werden können, die andere Arraylisten in Java enthalten und alle seine internen Elemente in ein einzelnes Array verschmelzen. Der Artikel bietet zwei Kernlösungen durch den Flatmap -Betrieb der Java 8 -Stream -API: Zuerst in eine Liste und dann das Ausfüllen des Arrays und das direkte Erstellen eines neuen Arrays, um die Anforderungen verschiedener Szenarien zu erfüllen.

Java Generics und Wildcards verstehen Java Generics und Wildcards verstehen Sep 20, 2025 am 01:58 AM

Javagenericsprovidecompile-timetypesafetyandeliminatecastingbyallowingtypeparametersonclasses,interfaces,andmethods;wildcards(?,?extendsType,?superType)handleunknowntypeswithflexibility.1.UseunboundedwildcardwhentypeisirrelevantandonlyreadingasObject

See all articles