HTTP超文件传输协议基础

一、概念

HTTP(HyperText Transfer Protocol,超文本传输协议)是一种用于分布式、协作式、超媒体信息系统的网络协议。它定义了客户端和服务器之间请求和响应的格式。HTTP 是基于TCP/IP协议的应用层协议,通常用于网页浏览。

超文本:超链接&文本

二、特性

1、C/S模型

总是客户端向服务端发送请求(request),服务端处理请求并做出回复(respond),请求和回应一一对应,这样的请求回应组合称为HTTP中的事务,不同事务之间相互独立,在应用层具有无连接性(逻辑上断开了连接,实际上可能没有断开)。

2、无状态

HTTP协议本身是无状态的,这意味着服务器不会在请求之间保存任何关于客户端状态的信息。

3、可靠性

底层采用tcp协议传输,保证了可靠性。

三、URI/URL

URI(Uniform Resource Identifier,统一资源标识符)和URL(Uniform Resource Locator,统一资源定位符)是互联网上用于标识资源的两种重要概念。

URI(统一资源标识符)

URI是一种用于标识资源的字符串,它提供了一种唯一的方式来标识互联网上的资源。URI可以进一步分为两种类型:

  1. URL(统一资源定位符):URL是URI的一种,它不仅标识资源,还提供了定位资源的方法,即如何访问该资源。URL包含了访问资源所需的所有信息,如协议、服务器地址、路径等。

  2. URN(Uniform Resource Name,统一资源名称):URN是URI的另一种类型,它用于持久、唯一地标识资源,但不包含如何访问资源的信息。URN通常用于那些不会频繁改变位置的资源,如书籍、文章等。

URL(统一资源定位符)

URL是URI的一种,它提供了一种具体的方式来定位和访问互联网上的资源。一个典型的URL包含以下几个部分:

  1. 协议(Scheme):指定访问资源所使用的协议,如httphttpsftp等。

  2. 服务器地址(Authority):指定资源所在的服务器地址,通常包括域名和端口号(如果非默认端口)。

  3. 路径(Path):指定资源在服务器上的路径。

  4. 查询字符串(Query):可选,用于传递额外的参数信息,如搜索关键词、页面编号等。

  5. 片段标识符(Fragment):可选,用于指向资源内部的特定部分,如网页中的某个章节。

示例:https://www.example.com/path/to/resource?query=param#fragment

  • https:协议
  • www.example.com:服务器地址
  • /path/to/resource:路径
  • ?query=param:查询字符串
  • #fragment:片段标识符

四、MIME

MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展)是一种互联网标准,用于处理不同格式的电子邮件内容。它最初被设计用于电子邮件,但后来也被广泛应用于HTTP协议中,用于定义和传输不同类型的数据。

MIME的主要目的是:

  1. 定义数据格式:MIME类型(也称为媒体类型)用于指定文件或消息内容的格式。例如,text/html表示HTML文档,image/jpeg表示JPEG图片,application/json表示JSON数据等。

  2. 支持多种数据类型:MIME允许电子邮件和网页支持多种数据类型,包括文本、图片、音频、视频等。

  3. 编码机制:为了确保数据在传输过程中的完整性,MIME定义了一种编码机制,如Quoted-printable和Base64,用于处理非ASCII字符和二进制数据。

  4. 头部信息:MIME头部信息用于描述消息的内容和格式。例如,在HTTP响应中,Content-Type头部用于指定响应体的MIME类型。

一些常见的MIME类型包括:

  • text/plain:纯文本文件,如TXT文件
  • text/html:HTML文档
  • image/jpeg:JPEG图片。
  • image/png:PNG图片。
  • image/gif:GIF图片。
  • application/pdf:PDF文档。
  • application/json:JSON数据。
  • application/xml:XML数据。
  • multipart/form-data:用于表单数据的传输,允许在单个请求中发送多个数据字段。

 五、探究HTTP报文结构

报文的结构:

  • 报头
  • 载荷

1、请求报文

可以接受HTTP接受请求的服务端程序

class HttpServer{
public:
    HttpServer(string ip,unsigned short port)
        :_sockfd(-1),_ip(ip),_port(port)
    {}
    ~HttpServer(){
        if(_sockfd>0){
            close(_sockfd);
        }
    }
    void start();
    void recvMsg();
    string response();
private:
    int _sockfd;
    string _ip;
    unsigned short _port;
};
void HttpServer::start(){
    _sockfd=::socket(AF_INET,SOCK_STREAM,0);
    if(_sockfd<0){
        perror("socket");
        return ;
    }
    int reuse=1;
    int ret=::setsockopt(_sockfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse));
    if(ret<0){
        perror("setscokopt");
        return ;
    }
    struct sockaddr_in serverAddr;
    ::bzero(&serverAddr,sizeof(serverAddr));
    serverAddr.sin_family=AF_INET;
    serverAddr.sin_port=htons(_port);
    serverAddr.sin_addr.s_addr=inet_addr(_ip.c_str());
    ret=::bind(_sockfd,(struct sockaddr *)&serverAddr,sizeof(struct sockaddr_in));
    if(ret<0){
        perror("bind");
        return;
    }
    ::listen(_sockfd,50);
}
void HttpServer::recvMsg(){
    while(true){
        int netfd=::accept(_sockfd,nullptr,nullptr);
        char buf[4096]={0};
        ssize_t sret=recv(netfd,buf,sizeof(buf),0);
        cout<<"sret="<<sret<<" buf="<<buf<<endl;
        string resp=response();
        send(netfd,resp.c_str(),resp.size(),0);
        close(netfd);
    }
}

通过浏览器充当客户端向该程序发送请求,该程序执行接受请求并打印的操作,获得的http请求报文如下:

sret=481 buf=GET / HTTP/1.1  #方法 路径 版本
Host: 192.168.80.132:1234    #地址
Connection: keep-alive       #长连接
Content-Length: 0            #报文长度
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0
#客户端类型

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6

请求报文的报头结构如上图所示:

  • 起始行:方法+路径+版本 (\r\n)
  • 若干键值对(\r\n)
  • 空行(报头长度未知,用来空行判断报头结束的标准,报文长度记载在报头,长度已知)(\r\n)

请求报文中的方法种类:

  1. GET:用于请求从服务器检索特定资源。GET请求应该只检索数据而不产生其他效果。GET是最常用的方法,用于获取网页内容。

  2. POST:用于向服务器提交数据进行处理(例如,提交表单或上传文件)。POST请求可能会导致新资源的创建或现有资源的修改。

  3. PUT:用于上传文件至服务器。PUT请求通常用于更新现有资源或创建新资源。

  4. DELETE:用于请求服务器删除指定的资源。

  5. HEAD:请求获取与GET请求相同的响应,但没有响应体。主要用于检查资源是否存在,以及获取资源的元数据。

  6. OPTIONS:用于描述目标资源的通信选项。它允许客户端查看服务器的性能。

  7. PATCH:用于对资源进行部分修改。与PUT不同,PATCH只更新资源的部分内容,而不是整个资源。

  8. CONNECT:用于将请求连接转换为一个透明TCP/IP隧道,常用于SSL加密服务器的链接(通过代理)。

  9. TRACE:用于沿着请求/响应链回显收到的请求,测试或诊断问题。

 HTTP版本:

HTTP1.0和1.1的区别:1.1支持连接复用,节省了处理TCP连接的时间

2、响应报文

在linux环境执行curl -I  域名(www.xx.com)可以得到响应报文:

HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 28 Oct 2024 11:00:09 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://dn.com/en-us/sale/jb.com

响应报文的报头结构:

  • HTTP版本+状态码
  • Server:服务器名称
  • Content-Type:MIME类型
  • Content-Length:报文长度

HTTP状态码:

  1. 1xx(信息性状态码):表示接收的请求正在处理。

    • 100 Continue:服务器已接收到请求的初始部分,客户端应继续发送其余部分。
    • 101 Switching Protocols:服务器已理解请求,并将通过Upgrade头转换到不同的协议。
  2. 2xx(成功状态码):表示请求已成功被服务器接收、理解、并接受。

    • 200 OK:请求成功。
    • 201 Created:请求成功,并且服务器创建了新的资源。
    • 202 Accepted:服务器已接受请求,但尚未处理。
  3. 3xx(重定向状态码):表示需要进一步操作以完成请求。

    • 301 Moved Permanently:请求的资源已被永久移动到新位置。
    • 302 Found:请求的资源临时被移动到另一个URI。
    • 304 Not Modified:自从上次请求后,资源未修改过。
  4. 4xx(客户端错误状态码):表示客户端似乎有错误。

    • 400 Bad Request:服务器无法理解请求,可能是由于客户端错误。
    • 401 Unauthorized:请求需要用户的身份认证。
    • 403 Forbidden:服务器理解请求,但是拒绝执行。
    • 404 Not Found:服务器找不到请求的资源。
    • 408 Request Timeout:请求超时。
  5. 5xx(服务器错误状态码):表示服务器在处理请求的过程中发生了错误。

    • 500 Internal Server Error:服务器遇到了一个未曾预料的状况,导致无法完成对请求的处理。
    • 501 Not Implemented:服务器不支持请求的功能,无法完成请求。
    • 503 Service Unavailable:服务器目前无法处理请求,可能是由于过载或停机维护。

服务端向客户端发送报文:

string HttpServer::response(){
    string startLine="HTTP/1.1 200 OK\r\n";
    string headers="Server: kkHttpServer\r\n";
    string body="<html>Hello World</html>";
    headers+="Content-Type: text/plain\r\n";
    headers+="Content-Length: "+std::to_string(body.size())+"\r\n";
    string emptyLine="\r\n";
    return startLine+headers+emptyLine+body;
}

浏览器客户端得到html文件并展示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值