HTTP协议详细总结(协议格式,协议实现)


前言

应用层:直面程序员的一层,因为应用程序是程序员自己写的,因此应用层的协议都是程序员自己定的
自定制协议:程序员自己设计的协议-----涉及到数据传输性能,数据的解析性能
序列化:将各个数据对象按照指定的协议组织成为持久化存储/数据传输的二进制数据串
反序列化:将二进制数据串按照指定协议解析得到各个数据对象

比较常用的序列化方式:json序列化/protobuf/二进制序列化
一个序列化方式的好坏有很多评定标准:解析性能/传输性能
下面我们说说知名协议:HTTP

HTTP协议

超文本传输协议–早期专门用于传输超文本数据html,但是随着协议发展多元化,不限制数据格式.。

网址:统一资源定位符:URL----在网络中唯一标记定位一个资源
如何定位—URL中包含的元素:

  • 协议方案名称://认证用户名:认证密码@服务器IP地址:服务器处理进程端口/请求的资源路径?查询字符串#片段标识符
  • http://username:password@www.baidu.com:80/index.html?name=hedenghui&age=18#ch
  • 服务器IP地址:我们看到的不一定是IP地址,也可能是一个域名–服务器的别名—通过域名解析服务器就能得到服务器IP地址
  • 服务器端口:web服务器默认http服务器端口是80 端口,默认不显示
  • /请求的资源路径:资源在服务器上的路径,这里的/是http根目录,但是是一个服务器上的相对根目录,只是一个子目录
  • 查询字符串:客户端提交给服务端的一些数据,由key=val&key=val形式的键值对组成
查询字符串中不能出现特殊字符:因为url中特殊字符都有特殊含义,一旦提交的数据有特殊字符,就会造成歧义。因此若提交的数据中有特殊字符,则需要进行数据转义
urlencode:url编码,将特殊字符每一个字节,转换为16进制的数字字符,并且使用%前缀作为转义标识  举例:+-->%2b
urldecode:url解码,在url中遇到%,则认为其后两个字符需要转义,将第一个字符转换成数字乘以16,加上第二个字符转换的数字
  • 片段标识符:html中的一个标签id,直接跳转到页面的某个位置

HTTP协议实现

HTTP协议是一个字符串明文协议(将多个数据对象组成一个指定格式的字符串进行数据传输)
HTTP协议就是应用程序之间沟通的数据格式约定,在传输层使用TCP协议实现传输,浏览器向服务器请求一个网页的时候,要搭建一个TCP客户端,我们所说的HTTP服务器实际上本质就是一个TCP服务器
抓包工具:wireshark/fiddler
wireshark:网卡抓包工具,抓取流经网卡的所有数据流量–什么包都能抓
fiddler:浏览器的代理工具,通过代理实现数据抓包—专业的http抓包工具
在这里插入图片描述

HTTP协议格式

协议格式:
首行:请求或响应的第一行数据
头部:请求或响应中的一些关键描述信息字段
空行:间隔头部与正文
正文:请求提交的数据或响应返回的数据

  • 请求

首行GET http://123.207.58.25/admin HTTP/1.1

通过看空格进行间隔包含三个要素,并最终以 /r/n 作为结尾
请求方法GET/POST/HEAD/PUT/DELETE/CONNECT/PATCH/OPTIONS/TRACE
在这里插入图片描述

  • GET----请求实体资源-也可以通过url中查询字符串向服务器提交数据—数据不安全/url长度有限制
  • POST—主要用于向服务器提交数据,提交的数据在正文中;put请求与post一样都会改变服务器的数据,但是put的侧重点在于对于数据的修改操作,但是post侧重于对于数据的增加
  • HEAD—类似于GET,只是head只要响应头部,而不要响应正文
GET/POST:GET请求没有正文,POST请求有正文

URL:http://123.207.58.25/admin

协议版本HTTP/1.1--------0.9/1.0/1.1/2.0

  • 0.9:这时候的http仅用于传输html数据,并且只有GET请求方法,并且协议格式不完整

  • 1.0:正式规定了http协议格式,并且增加了多种请求方法,并且支持了不同文件格式的数据流,传输性能并不高,仅支持短连接----简单的请求响应

  • 1.1:在1.0的基础上增加了更多请求方法和头部描述信息,并且支持了长连接,管线化传输,完善了缓存1机制

  • 2.0:采用二进制流传输,并且进行连接复用,并且允许服务端主动推送数据

    短连接:http基于在传输层tcp实现通信,短连接指的是建立连接,发送一个请求,得到响应之后,则关闭连接
    长连接:一次连接可以发送多条请求
    

在这里插入图片描述

请求头部:描述本次请求的关键字段信息,由key:val形式的键值对组成,并且每个键值对以\r\n作为结尾

  • Connection–控制长(Keep live)/短连接(close)
  • Cache-Control–缓存控制
  • User-Agent–客户端的属性
  • Accept–描述自己所能接收的数据属性
  • Content-Length–描述正文长度
  • Content-Type–描述符正文数据类型
  • Referer–表示当前请求从哪个连接跳转而来
  • Cookie:早期http是短连接通信,是一个无状态协议,不会保存客户端的状态,每次访问都需要重新登陆,因此引入Cookie保存客户端状态,Cookie中可以带有一些信息,持续在通信中描述客户端的通信状态,但是不够安全

空行:间隔头部与正文,\r\n;接收http数据的时候,当连续接受两个\r\n的时候,则认为头部到此结束

先获取完整头部,通过头部中的Content-Length获取正文长度,然后获取指定长度正文,通过这种方式每次获取完整一条http请求数据

正文:提交给服务端的数据

  • 响应:

首行:HTTP/1.1 303 See Other

包含三个要素,以空格进行间隔,以\r\n作为结尾
协议版本:0.9/1.0/1.1/2.0
响应状态码:表示本次的请求服务端所作出的响应结果
1xx:描述信息,协议切换
2xx:表示本次请求正确处理完毕 典型:200
3xx:重定向–你请求的资源在另一个位置,要求客户端重新请求新的位置

  • 301:永久重定向(没有关闭情况下下次不经过这个原先路径,直接请求新路径)

  • 302:临时重定向(没有关闭情况下下次请求还是需要先请求原先路径,然后请求新的位置)

    4xx:表示客户端请求错误;

  • 400:请求错误

  • 404:表示请求的资源不存在

    5xx:表示服务端错误

  • 500:服务器内部错误

  • 502:代理请求失败/无效响应

  • 504:代理请求超时

状态码描述:对状态码的描述信息,可以是官方文档,也可以自定义
头部:关于本次响应的一些关键字段描述信息,以key:val键值对组成,以\r\n作为结尾

  • Transfer-Encoding:实体正文的传输方式

  • Expires:缓存过期时间

  • Location-3xx重定向的新位置

  • Set-Cookie—服务端通过set-cookie向客户端传递信息,会被保存在客户端浏览器的cookie文件中

    Cookie---客户端每次通信从cookie文件读取数据通过cookie向服务端传递信息(维持客户端状态使用)
    cookie的使用不太安全因此使用Session搭配使用
    Session---会话,服务端会为每个登陆的客户端创建会话,在服务端描述一些会话信息(客户端身份信息,状态信息)保存在服务端,可以通过cookie将session id返回给客户端,客户端每次通信都会通过cookie带有自己的session id;
    

Cookie和session有什么区别:
Cookie是保存在客户端的数据,每次请求服务端时通过Cookie字段发送给服务器,来维持客户端状态
Session是保存在服务端的客户端会话信息,服务端为每个客户创建会话信息保存客户端状态,通过Set-cookie返回给客户端,session id防止隐私泄露,维持客户端状态

在这里插入图片描述

简单实现一个HTTP服务器

#include"tcpsocket.hpp"
#include<iostream>
#include<sstream>
int main()
{
        TcpSocket lst_sock;
        CHECK_RET(lst_sock.Socket());
        CHECK_RET(lst_sock.Bind("172.24.3.182",9000));
        CHECK_RET(lst_sock.Listen());
        while(1)
        {
                TcpSocket con_sock;
                lst_sock.Accept(&con_sock);
                std::string buf;
                con_sock.Recv(&buf);
                std::cout<<"请求信息:["<<buf<<"]\n";


                std::string body;
                body="<html><body><h1>hello world</h1></body></html>";
                std::string empty_line="\r\n";
                std::stringstream header;
                header<<"Content-Type: text/html\r\n";
                header<<"Content-Length: "<<body.size();
                header<<"Connection: close\r\n";
                header<<"Location: http://www.taobao.com\r\n";
                std::string first_line;
                first_line="HTTP/1.1 302 OK\r\n";

                con_sock.Send(first_line);
                con_sock.Send(header.str());
                con_sock.Send(empty_line);
                con_sock.Send(body);

                con_sock.Close();
        }
        lst_sock.Close();
        return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值