应用层典型协议–http协议
文章目录
前言
在数据的封装与分用中,当数据到达每一层的时候,都会被封装或是被分用,而应用层典型协议就是HTTP协议。
tcp/ip模型 | 典型协议 | 含义 |
---|---|---|
应用层 | HTTP 、FTP、DNS、SMTP | 不同程序间有不同的数据格式 |
传输层 | TCP、UDP | 提供两端进程间的数据传输,描述了通信两端端口 |
网络层 | IP | 提供地址管理与路由选择,描述了通信两台主机的IP地址 |
数据链路层 | ETH | 提供相邻设备的数据帧传输,描述了相邻设备的mac地址 |
物理层 | 以太网协议 | 在物理层进行一些约定 |
HTTP,超文本传输协议。
一、 URL认识
统一资源定位符,即我们所说的网址,功能就是定位网络上某一台主机上的某一个资源。
urlencode和urldecode
url的编码和解码。
像 /
?
:
等这样的字符,实际上已被url当做特殊意义理解了,故这些字符是不能随意出现的。比如,某个参数中需要带有这些特殊字符,就必须先对特殊字符进行转义。
转义的规则如下:
将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式。
二、HTTP协议
特性:
- 基于字符串明文传输,调试便捷性高
- 一种简单的请求的响应格式
- 基于tcp协议,传输安全可靠
实现一个简单的http服务器,在网页上打印“hello world”。
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void Usage()
{
printf("usage: ./server [ip] [port]\n");
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
Usage();
return 1;
}
//创建套接字
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0)
{
perror("socket");
return 1;
}
//绑定地址信息
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(argv[1]);
addr.sin_port = htons(atoi(argv[2]));
int ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0)
{
perror("bind");
return 1;
}
//监听套接字
ret = listen(fd, 10);
if (ret < 0)
{
perror("listen");
return 1;
}
//循环对套接字进行监听和进行通信连接,数据收发等
while(1)
{
//获取新建连接
struct sockaddr_in client_addr;
socklen_t len;
int client_fd = accept(fd, (struct sockaddr *)&client_addr, &len);
if (client_fd < 0)
{
perror("accept");
continue;
}
char input_buf[1024 * 10] = {0}; // 用一个足够大的缓冲区直接把数据读完
ssize_t read_size = read(client_fd, input_buf, sizeof(input_buf) - 1);
if (read_size < 0)
{
return 1;
}
printf("[Request] %s", input_buf);
char buf[1024] = {0};
const char *hello = "<html><body><h1>hello world</h1></body></html>";
sprintf(buf, "HTTP/1.0 200 OK\nContent-Length:%lu\n\n%s", strlen(hello), hello);
write(client_fd, buf, strlen(buf));
}
return 0;
}
(1)网页输入http://ip:port
。
服务端显示结果:
(2)网页输入http://ip:port/index.html
。
服务端显示结果:
1 HTTP协议格式
1.1 http请求格式
http请求分为四个部分,分别是请求行(首行)、请求头部、空行、正文。
请求行
:请求中的第一行,主要对请求进行关键性描述。请求头部
:请求的属性,冒号分隔的键值对,对于请求的附加描述以及对正文的描述。空行
:间隔头部与正文。正文
:提交给服务器的数据。
- 请求行:三部分内容,以空格作为间隔,请求行以
\r\n
作为结尾。
http请求方法:
- 请求头部:针对请求的一些附加描述,以及对于请求正文的描述。
请求头部分类:
类别 | 描述 |
---|---|
请求头部 | 只会在请求中出现的字段,用于描述请求 |
正文头部 | 在请求与想用中都会出现,主要是对于正文的描述 |
响应头部 | 只会在响应中出现的头部字段,描述响应 |
通用头部 | 在请求与响应中都会出现,属于对于本次通信或者连接的一些描述 |
Connection: keep-alive/close
,描述当前的连接使用的是短连接还是长连接,keep-alive
表示长连接,close
为短连接。
实例:
1.2 http响应格式
http响应格式分为四个部分,分别是响应行(首行)、响应头部、空行、正文。
1.
响应行(首行)
:响应中的第一行,主要对响应进行关键性描述。
2.响应头部
:响应的属性,冒号间隔的键值对。
3.空行
:间隔头部与正文。
4.正文
:响应给客户端的数据。
- 响应行: 协议版本,状态码,状态码描述。如:
HTTP/1.1 200 OK\r\n
。
响应状态码:明确直接的向客户端表示本次请求的处理结果。
状态码描述:一个对于状态码的文字描述信息。
实例:
2 HTTP常见header字段
字段 | 描述 |
---|---|
Content-Type | 数据类型(text/html等) |
Content-Length | 请求正文长度 |
Host | 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上 |
User-Agent | 声明用户的操作系统和浏览器版本信息 |
referer | 当前页面是从哪个页面跳转过来的 |
location | 搭配3xx状态码使用, 告诉客户端接下来要去哪里访问 |
Cookie | 用于在客户端存储少量信息. 通常用于实现会话(session)的功能 |
3 头部字段中Cookie(请求头)和Set-Cookie(响应头)
头部字段中Cookie(请求头)和Set-Cookie(响应头):
http是一个简单的请求-响应的协议,不论是短连接还是长连接,它们的连接都不是持续的;这样就会存在一个问题,如,当我们登录淘宝网站,由于连接不是持续的,这样会导致我们每次要登录网站买东西时都得重新建立连接重新登录。这时候就需要,不管是不是原来的连接,都得区别出来用户,而cookie机制就是来解决此问题的。
cookie:一种信息缓存机制,将一些信息保存在客户端主机上,等下一次请求服务器的时候读取出来发送给服务器。
有了cookie机制,就可以很好的在多次通信中不断维护客户端的状态,但是该机制是不安全的,如果被劫持用户登录信息就会泄漏,故不可以将敏感信息进行传输。在此基础上,增加了session。
session:即会话,实质上就是为客户端与服务端的通信建立一个会话,将会话重要内容保存起来,会话内容被保存在服务器上,如此,客户端只需要通过cookie需要传输session_id即可,就不用传输相关内容,这样就不会在网络传输用户敏感信息。
session会话机制,是在cookie的机制上,避免了敏感信息的传输,提高了信息传输的安全性。
session和cookie区别:
- cookie:将关键信息保存在客户端本地,每次通信前发送给服务器。
- session:将会话信息保存在服务器上,通过session_id进行cookie的传输,保护用户信息的安全
三、 HTTPS协议
在http协议的基础上进行了一层加密,是http加密后的协议。
那为何要有个加密版本呢?
在网络通信的时候,我们都必须明确知道对方是谁,并且能够进行验证和通信的数据可以不被别人进行窃听盗取。
1 身份验证
加密传输:SSL、TLS。
加密:身份验证+加密传输。
通信身份验证:第三方权威机构+CA认证。
2 加密传输
加密传输:SSL、TLS。
对传输的数据进行加密,通信双方进行传输加密,需要进行密钥的协商。
对称加密:
数据的加密和解密是相同的密钥。
优点:加解密效率高
缺点:进行密钥协商的时候容易被劫持
非对称加密:
数据的加密和解密是不是相同的密钥。
- 思想:通过指定的算法(RSA)可以生成一对密钥(公钥和私钥),使用公钥进行数据加密,加密后的数据只能通过私钥来进行解密。
- 流程:连接建立成功后,将自己的公钥发送给对方,对方使用公钥加密要传输的数据,这个数据就只能使用私钥来进行解密。
优点:不怕被劫持
缺点:加解密效率低
那对称密钥不安全,非对称密钥效率低,所以又有混合加密来进行。
混合加密思想:
假设是客户端对服务端进行验证
- 服务器生成一对非对称密钥,连接建立成功,通信前将公钥发送给客户端
- 客户端收到后,使用公钥加密一个随机数A,以及自己支持的对称加密算法
- 服务器收到后,使用私钥进行解密,得到了随机数A和客户端的对称加密算法
- 服务器向客户端发送一个随机数B,以及自己支持的对称加密算法,客户端与服务器就可以各自根据两个随机数和支持的对称加密算法,计算出一个对称密钥,至此,对称密钥协商完毕
- 之后通信都使用对称密钥进行加密解密数据传输
在实际的SSL加密中,身份验证和加密传输是整合在一起的。
CA证书中包含了,通信方的公钥,机构信息,证书颁布机构信息,证书失效时间等。
单向的验证,以服务器验证为主,SSL加密流程如下:
- 服务器自己生成一对密钥,拿着公钥去第三方权威机构颁发证书
- 权威机构根据服务器的公钥,生成一个CA证书给服务器
- 客户端与服务器建立连接后,通信前,服务器先将CA证书发送给客户端
- 客户端在收到CA证书后,进行解析验证权威机构是否是自己信任的机构,在权威机构验证对方身份,解析出公钥
- 客户端生成一个随机数,使用公钥对随机数和自己支持的加密算法进行加密,发送给服务器
- 服务器收到数据后,使用私钥进行解密,然后生成自己的随机数,将随机数和自己支持的加密算法发送给客户端
- 客户端收到数据后,客户端和服务器都有对方的随机数和自己的随机数,以及各自支持的加密算法,然后进行计算得到一个对称密钥
- 之后客户端和服务器的通信,都使用协商出来的对称密钥进行数据传输