Jadual Kandungan
Memahami hubungan berterusan HTTP (Keep-Alive)
Salah faham dan analisis protokol biasa
1. Penyalahgunaan versi protokol HTTP
2. Sambungan: Kesan tajuk tindak balas yang rapat
3. Kepentingan sokongan sisi pelayan
Mengendalikan respons HTTP dengan betul dan sambungan yang berterusan
Rumah Java javaTutorial Pemahaman yang mendalam mengenai hubungan berterusan HTTP: Dasar dan amalan untuk menghantar pelbagai permintaan pada soket yang sama

Pemahaman yang mendalam mengenai hubungan berterusan HTTP: Dasar dan amalan untuk menghantar pelbagai permintaan pada soket yang sama

Sep 21, 2025 pm 01:51 PM

Pemahaman yang mendalam mengenai hubungan berterusan HTTP: Dasar dan amalan untuk menghantar pelbagai permintaan pada soket yang sama

Artikel ini meneroka mekanisme menghantar banyak permintaan HTTP pada soket TCP yang sama, iaitu, sambungan berterusan HTTP (Keep-Alive). Artikel ini menjelaskan perbezaan antara protokol HTTP/1.X dan HTTP/2, menekankan pentingnya sokongan pelayan untuk sambungan yang berterusan, dan bagaimana untuk mengendalikan sambungan dengan betul: Tepung Response Headers. Dengan menganalisis kesilapan biasa dan menyediakan amalan terbaik, kami berhasrat untuk membantu pemaju membina pelanggan HTTP yang cekap dan mantap.

Memahami hubungan berterusan HTTP (Keep-Alive)

Sambungan berterusan HTTP, juga dikenali sebagai HTTP Keep-Alive, membolehkan pelanggan menghantar dan menerima banyak permintaan dan respons HTTP pada sambungan TCP yang sama tanpa perlu menetapkan semula sambungan baru untuk setiap permintaan. Ini dengan ketara mengurangkan overhead jabat tangan TCP dan permulaan yang perlahan, dengan itu meningkatkan prestasi dan kecekapan. Dalam HTTP/1.1, sambungan berterusan adalah tingkah laku lalai melainkan sambungan: Tutup ditentukan secara eksplisit. HTTP/2 melangkah lebih jauh, memproses pelbagai permintaan dan respons serentak pada satu sambungan melalui multiplexing.

Walau bagaimanapun, pelaksanaan klien menghantar pelbagai permintaan pada soket yang sama memerlukan kerjasama yang betul antara klien dan pelayan. Pelanggan menghantar sambungan: Keep-Alive hanya permintaan, dan pelayan mempunyai hak untuk memilih sama ada untuk menerimanya.

Salah faham dan analisis protokol biasa

Apabila cuba melaksanakan hubungan yang berterusan, pemaju sering menemui beberapa salah faham:

1. Penyalahgunaan versi protokol HTTP

Kod asal cuba menghantar permintaan menggunakan rentetan protokol HTTP/2:

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

Ini adalah salah tanggapan umum. Http/2 dan http/1.x adalah dua protokol yang sama sekali berbeza:

  • HTTP/1.x adalah protokol berasaskan teks, dan setiap pasangan permintaan/tindak balas biasanya diproses secara berurutan.
  • HTTP/2 adalah protokol binari yang memperkenalkan ciri -ciri canggih seperti multiplexing, mampatan kepala, dan push pelayan. Ia memerlukan peningkatan protokol semasa fasa jabat tangan TLS melalui rundingan protokol lapisan aplikasi (ALPN), dan bukan hanya mengisytiharkan HTTP/2 dalam baris permintaan. Menggantikan HTTP/1.1 dengan HTTP/2 secara langsung tidak membenarkan pelayan HTTP/1.x memahami permintaan HTTP/2, tetapi sebaliknya akan membawa kepada kesilapan protokol. Untuk pelayan http/1.x, http/1.1 atau http/1.0 harus selalu digunakan.

2. Sambungan: Kesan tajuk tindak balas yang rapat

Apabila pelayan mengandungi sambungan: Tutup pada tajuk tindak balas, ia secara eksplisit mengarahkan klien untuk menutup sambungan TCP selepas menerima respons semasa. Ini bermakna bahawa walaupun klien menghantar sambungan: Keep-Alive dalam permintaan, keputusan pelayan masih muktamad.

Dalam contoh output:

 Http/1.1 200 OK
Kandungan panjang: 2
Kandungan-jenis: Teks/Plain
Sambungan: Tutup
Terima Ranges: Tiada

Pelayan secara eksplisit mengembalikan sambungan: Tutup, jadi selepas menghantar badan tindak balas semasa, ia menutup sambungan soket. Selepas membaca semua data, Reader.ReadLine () pelanggan akan kembali null kerana sambungan ditutup, menyebabkan gelung berakhir dan permintaan berikutnya tidak boleh dihantar pada soket yang sama.

3. Kepentingan sokongan sisi pelayan

Inti pelaksanaan sambungan berterusan adalah sama ada pelayan menyokong dan membolehkannya. Terutama pada peranti yang terkawal sumber, seperti mikrokontroler ESP32, timbunan HTTP mereka mungkin memilih untuk tidak melaksanakan atau membolehkan sambungan berterusan untuk memudahkan dan menjimatkan sumber. Dalam kes ini, pelayan boleh mendesak menutup sambungan tanpa mengira bagaimana klien meminta sambungan: Keep-Alive.

Mengendalikan respons HTTP dengan betul dan sambungan yang berterusan

Untuk mengendalikan beberapa permintaan HTTP dengan betul pada soket yang sama, keperluan pelanggan:

  1. Hantar header permintaan HTTP/1.1 yang betul : Pastikan baris permintaan menggunakan HTTP/1.1 dan termasuk pengepala tuan rumah. Sekiranya anda mengharapkan sambungan yang berterusan, anda boleh menghantar sambungan secara jelas: Keep-Alive, tetapi ini tidak wajib, kerana HTTP/1.1 adalah sambungan berterusan secara lalai.

     Permintaan string = string.format (
        "Dapatkan/%s http/1.1 \ r \ n" // menggunakan http/1.1
          "Tuan rumah: %s \ r \ n"
          "Sambungan: Keep-Alive \ r \ n" // secara eksplisit meminta sambungan berterusan "\ r \ n",
        X, HostName
    );
    output.write (permintaan);
    output.flush ();
  2. Betul membaca HTTP Response : Ini adalah langkah yang paling kritikal. Tanggapan HTTP terdiri daripada garis status, tajuk tindak balas, dan badan tindak balas. Apabila membaca respons, anda tidak boleh hanya gelung melalui ReadLine () sehingga anda kembali null, kerana ini akan menyekat sehingga sambungan ditutup. Cara yang betul untuk melakukannya ialah:

    • Baca baris Header Response mengikut baris : Sehingga garis kosong (\ r \ n) ditemui, header berakhir.
    • Parsing Headers Response : Khususnya, kandungan panjang dan tajuk sambungan.
      • Sekiranya terdapat kandungan, badan tindak balas bilangan bait yang ditentukan dibaca.
      • Jika pengekodan pemindahan: Chunked wujud, badan tindak balas dibaca oleh peraturan pengekodan chunking.
      • Selesaikan Header Sambungan: Jika pelayan bertindak balas terhadap sambungan: Tutup, pelanggan harus menutup soket selepas membaca respons semasa. Jika anda bertindak balas terhadap sambungan: Keep-Alive (atau tidak ditentukan, HTTP/1.1 lalai), anda boleh cuba menghantar permintaan seterusnya.

Contoh: Logik baca responsif yang lebih mantap (versi mudah, tidak dihuraikan sepenuhnya untuk semua butiran HTTP)

Coretan kod berikut menunjukkan cara membaca respons dan memutuskan sama ada untuk meneruskan berdasarkan tajuk sambungan:

 import java.io.*;
import java.net.socket;
import java.net.url;
import java.util.hashmap;
import java.util.map;

kelas awam httpclientrobust {

    soket soket peribadi;
    output printwriter peribadi;
    Pembaca BufferedReader Private;
    Hostname String Private;
    Boolean Private Keepalive = true; // Andaikan bahawa pada mulanya mengharapkan untuk memastikan sambungan awam httpclientrobust () melemparkan ioException {
        Url url = url baru ("http://192.168.178.56"); // Ganti dengan IP ESP32 anda
        hostName = url.gethost ();
        int port = 80;

        soket = soket baru (nama host, port);
        output = printWriter baru (socket.getOutputStream ());
        pembaca = bufferedReader baru (inputStreamReader baru (socket.getInputStream ()));
    }

    public void sendAndReceive (String Path) melemparkan ioException, tergangguException {
        jika (! Keepalive) {
            System.out.println ("Sambungan ditutup oleh pelayan. Tidak dapat menghantar lebih banyak permintaan pada soket ini.");
            kembali;
        }

        Permintaan string = string.format (
            "Dapatkan /%s http /1.1 \ r \ n"
              "Tuan rumah: %s \ r \ n"
              "Sambungan: Keep-Alive \ r \ n" // Permintaan pelanggan untuk menyimpan sambungan "\ r \ n",
            jalan, nama host
        );

        System.out.println ("--- permintaan penghantaran ---");
        System.out.println (permintaan);
        output.write (permintaan);
        output.flush ();

        System.out.println ("--- menerima respons ---");
        Peta <string string> headers = hashMap baru  ();
        Garis rentetan;
        int contentLength = -1;

        // Baca baris baris status = reader.readline ();
        jika (line == null) {
            System.out.println ("Sambungan Tertutup Server.");
            KeepAlive = false;
            kembali;
        }
        System.out.println (line); // baris status cetak // header tindak balas membaca dan parse sementara ((line = reader.readline ())! = Null &&! Line.isempty ()) {
            System.out.println (line);
            int colonindex = line.indexOf (':');
            jika (colonindex> 0) {
                String headerName = line.substring (0, colonIndex) .trim ();
                String headervalue = line.substring (ColonIndex 1) .trim ();
                headers.put (headername.tolowerCase (), headervalue);
            }
        }

        // Semak Header Sambungan Jika ("Tutup" .EqualSignOrecase (Headers.get ("Sambungan"))) {
            KeepAlive = false;
            System.out.println ("Server diminta untuk menutup sambungan.");
        }

        // semak kandungan panjang
        jika (headers.containskey ("kandungan panjang")) {
            Cuba {
                contentLength = integer.parseInt (headers.get ("content-length"));
                System.out.println ("Kandungan-panjang:" ContentLength);
                // Baca badan tindak balas char [] buffer = char baru [contentLength];
                int bytesread = 0;
                manakala (bytesread <contentlength int result="reader.read" bytesread contentlength jika system.out.println sambungan ditutup sebelum membaca kandungan penuh. keepalive="false;" rehat response: string baru tangkapan e system.err.println panjang tidak sah. else sekiranya ada dan ia dipotong pelayan secara eksplisit kemudian baca sehingga ini terpakai dalam yang berterusan. akhirnya harus dinilai oleh atau pengekodan pemindahan. untuk kes di mana menghantar sambungan: tutup contoh anda boleh terus batal ditentukan. eof. stringbuilder responsebody="new" sementara reader.readline null reader.ready elakkan menghalang responsbody.append .append n> 0) {
                System.out.println ("Body Response:" ResponseBody.ToString (). Trim ());
            }
        }

        jika (! Keepalive) {
            tutup ();
        }
    }

    public void close () melemparkan ioException {
        jika (soket! = null &&! socket.isclosed ()) {
            socket.close ();
            System.out.println ("soket ditutup.");
        }
    }

    public static void main (string [] args) melemparkan ioException, tergangguException {
        Httpclientrobust client = null;
        Cuba {
            pelanggan = baru httpclientrobust ();
            untuk (int i = 1; i <p> <strong>Nota:</strong></p>
<ul>
<li> Reader.READ (buffer, bytesread, contentLength - bytesread) Dalam contoh di atas adalah cara yang betul untuk membaca badan tindak balas panjang tetap.</li>
<li> Reader.ready () mungkin tidak boleh dipercayai apabila membaca badan tindak balas, kerana data mungkin masih dalam transit tetapi belum mencapai penampan. Pelanggan HTTP yang lebih mantap memerlukan logik yang lebih kompleks untuk mengendalikan pelbagai pengekodan pemindahan (seperti pemindahan chunked) dan masa tamat.</li>
<li> Jika pelayan bertindak balas terhadap sambungan: Tutup, bendera Keepalive akan ditetapkan kepada permintaan palsu dan seterusnya tidak akan dihantar.</li>
</ul>
<h3> Ringkasan dan amalan terbaik</h3>
<ol>
<li><p> <strong>Memahami Perbezaan Protokol</strong> : HTTP/1.x dan HTTP/2 adalah protokol yang berbeza. Jangan mengelirukan penggunaannya. Untuk perkhidmatan web yang paling mudah, HTTP/1.1 adalah mencukupi, dan sambungan berterusannya adalah tingkah laku lalai.</p></li>
<li><p> <strong>Hormati Niat Pelayan</strong> : Sambungan Permintaan Pelanggan: Keep-Alive hanya cadangan, dan tajuk tindak balas sambungan pelayan (terutamanya sambungan: Tutup) mempunyai keputusan muktamad. Sentiasa periksa tajuk respons pelayan.</p></li>
<li><p> <strong>Betul menghuraikan tindak balas</strong> : Jangan bergantung pada gelung readline () sehingga ia kembali null untuk menentukan akhir respons, yang salah untuk sambungan yang berterusan. Kandungan panjang atau pengekodan pemindahan mesti dihuraikan untuk menentukan sempadan badan tindak balas.</p></li>
<li><p> <strong>Pertimbangkan keupayaan pelayan</strong> : terutamanya untuk peranti tertanam (seperti ESP32), timbunan HTTPnya mungkin mempunyai fungsi terhad. Jika pelayan tidak menyokong sambungan berterusan, pelanggan harus bersedia untuk mewujudkan sambungan baru untuk setiap permintaan.</p></li>
<li>
<p> <strong>Gunakan Perpustakaan Pelanggan HTTP yang matang</strong> : Untuk komunikasi HTTP yang kompleks, sangat disyorkan untuk menggunakan Java terbina dalam java.net.httpurlconnection atau perpustakaan pihak ketiga seperti Apache httpclient, Okhttp, dan lain-lain. Timeouts, dan lain -lain, sangat memudahkan kerja pembangunan. Contohnya:</p>
<pre class="brush:php;toolbar:false"> import java.net.uri;
import java.net.http.httpclient;
import java.net.http.httprequest;
import java.net.http.httpresponse;
import java.time.duration;

kelas awam ModernHttpClientExample {
    public static void main (string [] args) melemparkan pengecualian {
        Httpclient client = httpclient.newBuilder ()
                .versi (httpclient.version.http_1_1) // Jelas gunakan http/1.1
                .ConnectTimeout (duration.ofseconds (10))
                .build ();

        untuk (int i = 1; i  response = client.send (permintaan, httpresponse.bodyhandlers.ofstring ());

            System.out.println ("Permintaan" I "ke /" Path);
            System.out.println ("Kod Status:" Response.StatusCode ());
            System.out.println ("Badan tindak balas:" response.body ());
            System.out.println ("Header Connection:" Response.Headers (). FirstValue ("Sambungan"). Orelse ("N/A"));

            // Perpustakaan HttpClient secara automatik mengendalikan sambungan berterusan. Jika pelayan mengembalikan sambungan: Tutup, ia menutup sambungan semasa dan menetapkan sambungan baru pada kali berikutnya ia meminta.
            Thread.sleep (1000);
        }
    }
}

Dengan mengikuti prinsip-prinsip ini, pemaju boleh menguruskan sambungan HTTP dengan lebih berkesan dan membina aplikasi web berprestasi tinggi dan boleh dipercayai.

Atas ialah kandungan terperinci Pemahaman yang mendalam mengenai hubungan berterusan HTTP: Dasar dan amalan untuk menghantar pelbagai permintaan pada soket yang sama. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Stock Market GPT

Stock Market GPT

Penyelidikan pelaburan dikuasakan AI untuk keputusan yang lebih bijak

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Cara membuat fail di Java Cara membuat fail di Java Sep 21, 2025 am 03:54 AM

UseFile.createenewfile () tocreateafileonlyifitdoesneteTexist, mengelakkan penulisan; 2.preferfiles.createFile () darinio.2formodern, safeFileCreationThatFailSiffileexists;

Bagaimana untuk menambah fail balang ke ClassPath di Java? Bagaimana untuk menambah fail balang ke ClassPath di Java? Sep 21, 2025 am 05:09 AM

Gunakan parameter -CP untuk menambah balang ke ClassPath, supaya JVM dapat memuatkan kelas dan sumber dalamannya, seperti Java -Cplibrary.Jarcom.Example.Main, yang menyokong pelbagai balang yang dipisahkan oleh titik -titik komisul atau kolon, dan juga boleh dikonfigurasikan melalui pembolehubah persekitaran kelas atau manifest.mf.

Bagaimana untuk melaksanakan antara muka di Java? Bagaimana untuk melaksanakan antara muka di Java? Sep 18, 2025 am 05:31 AM

Gunakan kata kunci untuk melaksanakan antara muka. Kelas perlu menyediakan pelaksanaan khusus semua kaedah dalam antara muka. Ia menyokong pelbagai antara muka dan dipisahkan oleh koma untuk memastikan kaedahnya adalah umum. Kaedah lalai dan statik selepas Java 8 tidak perlu ditulis semula.

Pemahaman yang mendalam mengenai hubungan berterusan HTTP: Dasar dan amalan untuk menghantar pelbagai permintaan pada soket yang sama Pemahaman yang mendalam mengenai hubungan berterusan HTTP: Dasar dan amalan untuk menghantar pelbagai permintaan pada soket yang sama Sep 21, 2025 pm 01:51 PM

Artikel ini meneroka mekanisme menghantar banyak permintaan HTTP pada soket TCP yang sama, iaitu, sambungan berterusan HTTP (Keep-Alive). Artikel ini menjelaskan perbezaan antara protokol HTTP/1.X dan HTTP/2, menekankan pentingnya sokongan pelayan untuk sambungan yang berterusan, dan bagaimana untuk mengendalikan sambungan dengan betul: Tepung Response Headers. Dengan menganalisis kesilapan biasa dan menyediakan amalan terbaik, kami berhasrat untuk membantu pemaju membina pelanggan HTTP yang cekap dan mantap.

Bagaimana cara membaca fail hartanah di Java? Bagaimana cara membaca fail hartanah di Java? Sep 16, 2025 am 05:01 AM

Gunakan kelas Properties untuk membaca fail konfigurasi Java dengan mudah. 1. Masukkan config.properties ke dalam direktori sumber, muatkannya melalui getClassLoader (). 2. Jika fail berada di laluan luaran, gunakan FileInputStream untuk memuatkannya. 3. Gunakan GetProperty (Key, DefaultValue) untuk mengendalikan kekunci yang hilang dan memberikan nilai lalai untuk memastikan pengendalian pengecualian dan pengesahan input.

Membina Aplikasi Extensible dengan Antara Muka Penyedia Perkhidmatan Java (SPI) Membina Aplikasi Extensible dengan Antara Muka Penyedia Perkhidmatan Java (SPI) Sep 21, 2025 am 03:50 AM

Javaspi adalah mekanisme penemuan perkhidmatan terbina dalam JDK, dan melaksanakan pengembangan dinamik berorientasikan antara muka melalui ServicEloader. 1. Tentukan antara muka perkhidmatan dan buat fail yang dinamakan dengan nama penuh antara muka di bawah Meta-INF/Services/, dan tulis nama yang berkelayakan sepenuhnya kelas pelaksanaan; 2. Gunakan serviceLoader.load () untuk memuatkan kelas pelaksanaan, dan JVM secara automatik akan membaca konfigurasi dan instantiate; 3. Kontrak antara muka harus dijelaskan semasa reka bentuk, keutamaan sokongan dan pemuatan bersyarat, dan menyediakan pelaksanaan lalai; 4. Senario aplikasi termasuk akses saluran pelbagai pembayaran dan pengesahan pemalam; 5. Perhatikan prestasi, classpath, pengasingan pengecualian, keselamatan benang dan keserasian versi; 6. Dalam Java9, menyediakan boleh digunakan dalam kombinasi dengan sistem modul.

Tutorial Java: Cara meratakan arraylist bersarang dan mengisi unsur -unsurnya ke dalam array Tutorial Java: Cara meratakan arraylist bersarang dan mengisi unsur -unsurnya ke dalam array Sep 18, 2025 am 07:24 AM

Tutorial ini terperinci bagaimana untuk memproses arraylists bersarang dengan cekap yang mengandungi arraylists lain di Java dan menggabungkan semua elemen dalamannya ke dalam satu array. Artikel ini akan menyediakan dua penyelesaian teras melalui operasi flatmap API Java 8 Stream: pertama meratakan ke dalam senarai dan kemudian mengisi array, dan secara langsung mewujudkan array baru untuk memenuhi keperluan senario yang berbeza.

Memahami Generik Java dan Wildcard Memahami Generik Java dan Wildcard Sep 20, 2025 am 01:58 AM

JavagenericsprovideCompile-timetypesafetyandeliminatecastingingbyallowingtypeparametersonclass, antara muka, andmethods; wildcards (?,? Extendstype ,? supertype) handleunknowntypeswithflexxibility.usoSoRdoRderWildwildwhoRderWildwildwildwildwilddwherwherwilderwilderwilderwilderwildloundwilder .1

See all articles