forord
HTTP-protokollen er en av de viktigste protokollene på Internett, selv om den virker enkel, men i praksis støter den ofte på problemer, og vi har støtt på den flere ganger. Det er lange forbindelser og pakkeparsing. Du kan ikke vite noe om HTTP-protokollen, du må forstå den grundig. Derfor skrev jeg denne serien for å dele problemene og erfaringene med HTTP-protokollen.
HTTP-protokollen har en header og en kropp for både forespørsels- og svarpakkene, og kroppen er ressursen du ønsker å hente, for eksempel en html-side, et jpeg-bilde, og headeren brukes til å lage visse konvensjoner. For eksempel blir klienten og serveren enige om noen overføringsformater, og klienten får først headeren, kjenner til noe formatinformasjon, og begynner deretter å lese innholdet.
Klient: Accept-Encoding:gzip (komprimer det for meg, jeg bruker trafikk, last det ned først og pakk det sakte ut)
Server 1: Innholdskoding: null (Ingen innholdskoding-header.) Jeg gir ikke komprimering, CPU-en er ikke gratis, vil du ha den)
Server 2: Innholdskoding: gzip (lagrer trafikk for deg, komprimerer den) Klient: Tilkobling: keep-alive (Storebror, vi har endelig bygget en TCP-tilkobling, vi skal bruke den neste gang)
Server 1: Tilkobling: keep-alive (ikke lett, fortsett å bruke)
Server 2: Tilkobling: lukk (Den som fortsetter å bruke den med deg, vår TCP er engangs, og vi må koble til neste gang vi finner den) HTTP-protokollen har ikke tre håndtrykk, og når en klient ber om ressurser fra serveren, skal serversiden vinne. Det finnes også noen headere som ikke har en forhandlingsprosess, men serveren forteller klienten direkte hva den skal gjøre. For eksempel er innholdslengden ovenfor det serveren forteller klienten hvor stor kroppen er. Men! Servitøren kan kanskje ikke si nøyaktig hvor stor kroppen er på forhånd. Serveren må skrive headeren først, og deretter bodyen; hvis du vil skrive body-casen i headeren, må du vite body-størrelsen på forhånd. Hvis brødteksten genereres dynamisk, vil serveren fullføre og deretter begynne å skrive headeren, noe som krever mye ekstra overhead, så det kan hende det ikke er innholdslengde i headeren.
Så hvordan vet klienten størrelsen på kroppen? Serveren forteller deg det på tre måter.
1. Serveren kjenner allerede ressursstørrelsen og forteller deg det gjennom innholdslengdehodet.
Content-Length:1076(body的大小是1076B,你读取1076B就可以完成任务了)
Transfer-Encoding: null
2. Serveren kan ikke vite størrelsen på ressursen på forhånd, eller er uvillig til å bruke ressurser på å beregne ressursens størrelse på forhånd, så den legger til en header i http-svarmeldingen kalt Transfer-Encoding:chunked, som betyr blokkoverføring. Hver blokk bruker et fast format, med størrelsen på blokken foran, dataene bak, og deretter den siste blokken med størrelse 0. På denne måten, når klienten parser, må den være oppmerksom på å fjerne noen ubrukelige felt.
Content-Length:null
Transfer-Encoding:chunked (接下来的body我要一块一块的传,每一块开始是这一块的大小,等我传到大小为0的块时,就没了)
3. Serveren kjenner ikke størrelsen på ressursen, og støtter ikke chunked transmission-modus, så det finnes verken innholds-lengde-header eller transfer-encoding-header. På dette tidspunktet må headeren som returneres av serveren være nær.
Content-Length:null
Transfer-Encoding:null
Connection:close(我不知道大小,我也用不了chunked,啥时候我关了tcp连接,就说明传输结束了)
|