prefácio
O protocolo HTTP é um dos protocolos mais importantes da Internet, embora pareça simples, mas na prática frequentemente encontra problemas, e já o encontramos várias vezes. Existem conexões longas e análise sintática de pacotes. Você não pode saber nada sobre o protocolo HTTP, deve entendê-lo completamente. Por isso, escrevi esta série para compartilhar os problemas e experiências do protocolo HTTP.
O protocolo HTTP possui um cabeçalho e um corpo para os pacotes de requisição e resposta, e o corpo é o recurso que você deseja obter, como uma página html, uma imagem jpeg, e o cabeçalho é usado para criar certas convenções. Por exemplo, o cliente e o servidor concordam em alguns formatos de transmissão, e o cliente primeiro recebe o cabeçalho, conhece algumas informações de formato e então começa a ler o corpo.
Cliente: Accept-Encoding:gzip (comprima para mim, estou usando tráfego, baixe primeiro e depois descompacte devagar)
Servidor 1: Codificação de Conteúdo: null (Sem cabeçalho de Codificação de Conteúdo.) Eu não dou compressão, o processador não é gratuito, você quer?)
Server 2: Content-Encoding:gzip (salve tráfego para você, comprima) Cliente: Conexão: keep-alive (Irmão mais velho, finalmente construímos uma conexão TCP, vamos usá-la na próxima vez)
Servidor 1: Conexão: manter vivo (não é fácil, continue usando)
Servidor 2: Conexão: fechar (Quem continuar usando com você, nosso TCP é de uso único, e teremos que reconectar na próxima vez que encontrarmos) O protocolo HTTP não possui três apertos de mão, e quando um cliente solicita recursos do servidor, o lado do servidor prevalecerá. Também existem alguns cabeçalhos que não têm um processo de negociação, mas o servidor diz diretamente ao cliente o que fazer. Por exemplo, o Comprimento do Conteúdo acima é o que o servidor diz ao cliente o tamanho do corpo. Mas! O garçom pode não conseguir dizer exatamente o tamanho do corpo antecipadamente. O servidor precisa escrever o cabeçalho primeiro, depois o corpo; se você quiser escrever o corpo do cabeçalho, precisa saber o tamanho do corpo com antecedência. Se o corpo for gerado dinamicamente, o servidor termina e começa a escrever o cabeçalho, o que exige muito overhead adicional, então pode não haver um comprimento de conteúdo no cabeçalho.
Então, como o cliente sabe o tamanho do corpo? O garçom te informa de três maneiras.
1. O servidor já sabe o tamanho do recurso e informa através do cabeçalho de conteúdo de comprimento.
Content-Length:1076(body的大小是1076B,你读取1076B就可以完成任务了)
Transfer-Encoding: null
2. O servidor não pode saber o tamanho do recurso antecipadamente, ou não está disposto a gastar recursos para calcular o tamanho do recurso antecipadamente, então ele adicionará um cabeçalho à mensagem de resposta http chamado Transfer-Encoding:chunked, que significa transferência de blocos. Cada bloco usa um formato fixo, com o tamanho do bloco na frente, os dados atrás dele e o último bloco com tamanho 0. Dessa forma, quando o cliente analisa, ele precisa prestar atenção em remover alguns campos inúteis.
Content-Length:null
Transfer-Encoding:chunked (接下来的body我要一块一块的传,每一块开始是这一块的大小,等我传到大小为0的块时,就没了)
3. O servidor não sabe o tamanho do recurso e não suporta o modo de transmissão em blocos, então não há o cabeçalho de comprimento de conteúdo nem o cabeçalho de codificação de transferência. Nesse momento, o cabeçalho retornado pelo servidor deve estar próximo.
Content-Length:null
Transfer-Encoding:null
Connection:close(我不知道大小,我也用不了chunked,啥时候我关了tcp连接,就说明传输结束了)
|