5.2.1 HTTP协议

全称HyperText Transfer Protocol,中文叫做超文本传输协议,它是一个应用层协议,基于TCP,默认使用80端口,传输超文本格式数据。超文本的意思是这种文本既适合人阅读,也适合计算机处理。

请求和应答

当客户端和服务器通信时,客户端发送的报文叫做请求,服务器回应的报文叫做应答。

用户代理(user agent)

当客户端发起请求时,发送请求的程序,叫做用户代理,常见的代理就是浏览器,比如chrome、firefox、IE等等

应答服务器

应答服务器保存着图片和html网页资源,当收到代理的请求时,服务器根据请求,响应给客户相应资源。常用的HTTP服务器软件有apache,iis,nginx等等。

请求和应答格式

请求格式:

GET / HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8

应答格式:

HTTP/1.1 200 OK
Date: Mon, 25 Apr 2016 15:29:54 GMT
Server: Apache/2.4.7 (Ubuntu)
Last-Modified: Mon, 25 Apr 2016 15:22:50 GMT
ETag: "29-53150bfe5bf20"
Accept-Ranges: bytes
Content-Length: 41
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

hello, this is a page from ubuntu/apache

请求和应答格式详解

请求格式:

字段 含义
GET / HTTP/1.1 客户端告诉服务器,这个请求是一个是个GET方法,使用协议HTTP 1.1,客户端向服务器的请求有GET、POST等方法,协议也有1.0,2.0等协议
Host: 127.0.0.1 客户端告诉服务器,客户端访问的站点名字,以前服务器比较贵(现在也贵),一台服务器往往会布置多个网站,比如www.aaa.com和www.bbb.com都在一起时,这个字段就有用了
Connection: keep-alive 客户端告诉服务器,连接要保持,不要断掉,客户端等会儿还要有数据来(其实是没有了,协议规定了如此),历史上HTTP设计用来做简单应答的,就是客户端请求啥,服务器给啥,然后大家就拜拜了。但是这样的话每次请求都是一次新的连接,比较恼火,然后聪明人就发明了keep-alive这种东西。在http1.0中,这个属性是可选的,但是在http1.1中,这个字段总是规定存在。
Accept: text/html,... 客户端告诉服务器,客户端这边能接收的数据格式是什么
Upgrade-Insecure-Requests: 1 客户端告诉服务器,升级安全请求,这个和安全相关
User-Agent: Mozilla/5.0 ... 客户端告诉服务器,用户代理是什么,服务器可以根据不同的代理,做出不同响应
Accept-Encoding: gzip, deflate, sdch 客户端告诉服务器,支持的编码是什么,直接传输比较大,可以使用gzip压缩一下的
Accept-Language: zh-CN,zh;q=0.8 客户端告诉服务器,客户端支持的语言

应答格式

字段 含义
HTTP/1.1 200 OK 服务器应答:成功

服务器应答如果是200,表示完全成功,一点儿问题都没有,服务器的应答编码有很多,这个应答也是将来排除代码bug的重要依据,应答机也记不住那么多,但是分类分得很好

1xx 表示临时性应答
2xx 表示正确
3xx 表示重定向
4xx 表示客户端错误
5xx 表示服务器错误


具体可以看以下博文
http://blog.sina.com.cn/s/blog_5677f07c0101a7pn.html
Date: Mon, 25 Apr 2016 15:29:54 GMT 服务器日期时间
Server: Apache/2.4.7 (Ubuntu) 服务器
Last-Modified: Mon, 25 Apr 2016 15:22:50 GMT 所请求资源的最后修改日期
ETag: "29-53150bfe5bf20" 客户端请求一个页面(A)。 服务器返回页面A,并在给A加上一个ETag。 客户端展现该页面,并将页面连同ETag一起缓存。 客户再次请求页面A,并将上次请求时服务器返回的ETag一起传递给服务器。 服务器检查该ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304(未修改——Not Modified)和一个空的响应体。
Accept-Ranges: bytes 告诉客户端,服务器支持区间,意味着客户端可以请求部分资源,请求部分资源就意味着支持断点续传
Content-Length: 41 内容长度
Keep-Alive: timeout=5, max=100 回答客户端的keepalive,告诉客户端,五秒内必须要数据,不然我关闭连接,再有就是你这个连接最多来100个报文,满100个之后也关闭
Connection: Keep-Alive
Content-Type: text/html 服务器响应数据的内容类型是text/html
hello, this is a page from ubuntu/apache

获取请求报文代码


#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h> 
#include <stdlib.h>
#include <unistd.h>

#define myerror(__err) do{perror(__err);exit(0);}while(0)

int main(int argc, char* argv[])
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(80);
    addr.sin_addr.s_addr = 0;

    int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
    if(ret < 0)
        myerror("bind");

    listen(fd, 5);

    int newfd = accept(fd, NULL, NULL);
    char buf[2048];
    recv(newfd, buf, sizeof(buf), 0);

    printf("%s\n", buf);

    return 0;
}

获取应答报文代码

#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>

#define myerror(__err) do{perror(__err);exit(0);}while(0)

int main(int argc, char* argv[])
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(80);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    int ret = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
    if(ret < 0)
        myerror("connect");

    char buf[] = "GET / HTTP/1.1\n"
        "Host: 127.0.0.1\n"
        "Connection: keep-alive\n"
        "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\n"
        "Upgrade-Insecure-Requests: 1\n"
        "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36\n"
        "Accept-Encoding: gzip, deflate, sdch\n"
        "Accept-Language: zh-CN,zh;q=0.8\n\n";

    send(fd, buf, sizeof(buf), 0);

    char resp[4096];
    recv(fd, resp, sizeof(resp), 0);

    printf("%s\n", resp);

    pause();

    return 0;
}

results matching ""

    No results matching ""