网络 应用层 HTTP的认识及实现(模拟实现一个简单的服务器)_http应用服务实现(1)

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

网址:例如我们平时打开的网页都有相对应的网址https://www.baidu.com/。网址是统一资源定位器,简称URL,定位网络中某台主机上的某个资源

URL的组成

协议方案名称://认证用户名:认证密码@服务器IP地址:服务器处理进程端口/请求的资源路径?查询字符串#片段标识符

http://username:password@www.baidu.com:80/index.html?name=WhiteShirtI&age=21#id

协议方案名称(常用):通信协议,通常使用http

认证用户名:认证密码(少用):用户的账号密码

服务器IP地址(常用):我们看到的不一定是IP地址,也可能是一个域名,也就是服务器的别名,通过域名解析服务器就能得到服务器的IP地址

服务器处理进程端口(常用):web服务器默认http服务器端口是80端口,默认不显示

/请求的资源路径(常用):资源在服务器上的路径,这里的/是http的根目录,但是是一个服务器的相对根目录,只是一个子目录。原因是省去前面重要的目录地址信息,防止用户访问

查询字符串:客户端提交给服务端的一些数据,由key=val&key=val形式的键值对组成的;查询的字符串不能出现特殊字符:因为url中特殊字符都是有特殊含义的,一旦提交的数据中有特殊字符,就会造成数据二义,因此若要提交的数据中有特殊字符,则需要进行数据转义;urlencode:url解码,提交的数据中不能出现特殊字符,一旦出现就要进行转义。将特殊字符每一个字节转换为16进制的数字字符,并且使用%前缀作为转义;+ 转义成 %2B ;解释:在ASSIC中+是代表数字43,转换成16进制就是2B
在这里插入图片描述

urldecode:url解码,在url中遇到%,则认为其后两个字符需要转义,将第一个字符转换成数字乘以16,加上第二个字符转换的数字。%2B 转义成 + ;解释:2*16+11=43, 将43转换为ASSIC码对应的符号

片段标识符:html中的一个标签id,直接跳转到页面的某个位置

HTTP协议请求格式

HTTP协议请求包含四个内容:首行、请求头部、空行、正文

首行

GET https://blog.csdn.net/qq_44443986?spm=1011.2124.3001.5113 HTTP/1.1 以空格进行间隔包含三个要素,并且最终以\r\n作为结尾
第一要素:请求方式:GET/POST/HEAD/PUT/DELETE/CONNECT/OPTIONS/TRACE/PATCH

  • GET-请求指定的页面信息,并返回实体主体,没有请求正文。也可以通过url中查询字符串向服务器提交数据,但是数据不安全 且 url长度有限制(各个服务器应用商的限制)
  • POST-向指定资源提交数据进行处理请求(例如提交表单或者上传文件),且提交的数据在请求正文中,相对GET比较安全 且无长度限制。
  • HEAD-类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头

第二要素:URL:网址信息
第三要素:协议版本:HTTP/1.1/0.9/1.0/2.0

  • HTTP/0.9-这时候的http仅用于传输html数据,并且只有GET请求方法,并且没有协议标准格式
  • HTTP/1.0-正式规定了http协议格式,并且增加了多种请求方法,并且支持了不同文件格式的数据流
  • HTTP/1.1-在1.0的基础上增加了更多请求方法和头部描述信息,并且支持了长连接管线化传输。(http基于在传输层tcp实现通信,短连接指的是建立连接后发送一个请求,得到响应之后就关闭连接;长连接指的是发送请求得到响应后并不会关不连接,当下次再来一次请求是还会使用当前这个连接,但这个连接不是永久存在的,当两端长时间没有交往时会自动断开;管线化传输指的是将多个HTTP请求整批提交的技术,而在传送过程中不需先等待服务端的回应 <响应的顺序必须与请求的顺序保证一致:1请求到2请求,必须等到1响应了2才能响应,存在线头阻塞问题>
  • HTTP/2.0-采用二进制流传输,并且支持多路复用,并且允许服务端主动推送数据 。(服务端主动推送数据是指请求一次,服务端会一次性推送所有数据,而不是一个请求,对应一个响应的数据;<利用多路复用,头部中标识了自己属于哪个流,解决了线头阻塞的问题,同时也提高了网络速度的利用率>)
头部

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

  • Connection-控制长/短连接
  • Cache-Control-缓存控制
  • User-Agent-客户端的属性
  • Accept-描述自己所能接收的数据属性
  • Content-Length-描述正文长度
  • Content-type-描述正文的数据类型
  • Get请求方式专属信息:Cookie-带有客户端的身份、状态等信息,客户端每次通信从cookie文件读取数据,通过cookie向服务端传递信息,(用于维护客户端状态信息)但是不够安全。Post则是将这些信息保存在正文中(安全)
空行

目的是间隔头部与正文,\r\n。接收http数据的时候,当连续接收两个\r\n的时候,则就认为头部到此结束。

正文

先获取完整头部,通过头部中的Content-Lenght获取正文长度,然后获取指定长度的正文,通过这种方式每次获取完整一条http请求数据
正文就是提交给服务端的数据

HTTP协议响应格式

HTTP协议响应包含四个内容:首行、请求头部、空行、正文

首行

HTTP/1.1 200 OK 以空格进行间隔包含三个要素,并且最终以\r\n作为结尾
第一要素:版本协议
第二要素:响应状态码
响应状态码是一个数字,这个数字表示本次的请求后服务端所做出响应的结果,这个结果分为五大类型:

  • 1xx:描述信息-服务器收到请求,需要请求者继续执行操作
  • 2xx:请求成功-操作被成功接收并处理;典型的有200-请求成功。一般用于GET与POST请求
  • 3xx:重定向-要求客户端重新请求新的位置;典型的有301-永久移动、302-临时移动
  • 4xx:客户端错误-请求包含语法错误或无法完成请求;典型的有400-请求错误;404-请求的资源不存在
  • 5xx:服务端错误-服务器在处理请求的过程中发生了错误;典型的有500-服务器内部错误,无法完成请求;502-服务器作为网关或代理尝试执行请求时,从远程服务器接收到了一个无效的响应;504-服务器作为网关或代理,但是没有及时从远程服务器收到请求,响应超时

第三要素:描述状态码
对状态码的描述信息,可以是官方文档对应的描述信息,也可以自定义描述信息

HTTP状态码大全

头部

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

  • Connection-控制长/短连接
  • Content-type-描述正文的数据类型
  • Server-包含有关用作原始服务器处理请求的软件信息
  • Transfer-Encoding-指定实体正文传输给客户端的方式,例如chunked-分块传输,将一个正文分为多块进行传输
  • Expires-缓存过期时间
  • Cache-Control-缓存控制
  • Set-Cookie-服务端通过set-cookie向客户端传递信息,会被保存在客户端浏览器的cookie文件中

由于cookie的使用不够安全,从而引入了Session,搭配cookie使用
Session-会话:服务端会为每个登录的客户端创建会话session,会话session保存了一些会话信息(客户端身份、状态信息等),并且session保存在服务端。可以通过cookie将session id返回给客户端,客户端每次通信都会通过cookie带有自己的session id,服务端就通过session id知道这是哪一个客户端了
图解:
在这里插入图片描述
cookie和session的区别:cookie是保存在客户端上的数据(用户信息),用于持续与服务端进行信息传递的一种手段;session是一种会话的控制,服务端保存的会话信息包含客户端的身份状态信息,通过cookie/set-cookie传递session_id进行客户端的身份状态识别

空行

目的是间隔头部与正文,\r\n。接收http数据的时候,当连续接收两个\r\n的时候,则就认为头部到此结束。

正文

正文就是提交给服务端的数据

HTTPS

HTTPS协议并不是一个新的协议,而是在HTTP协议基础上进行了一层加密。https协议是基于ssl进行加密实现的加密传输协议

安全传输需要考虑的问题:
1、身份验证问题:防止伪装
2、数据加密问题:防止监听

CA证书:通信双方在通信前先到权威机构请求给自己颁发一个CA证书

通信两方建立连接后,在通信之前先将证书发送给对方,收到对方的证书后,查看证书的权威机构是否是自己所信任的权威机构,如果是则到权威机构进行身份验证,通过后才进行通信

对称加密:服务器和浏览器使用的密钥都是同一个密钥
非对称加密:一个为公钥,一个为私钥,公钥和私钥之间不能相互推导,公钥加密需要私钥解密,私钥加密需要公钥解密
混合加密:通信时先使用非对称加密保护对称密钥协商的过程,直到对称密钥协商完后再使用对称加密进行传输

简单模拟实现HTTP服务器

实现流程

  1. 从键盘接收IP地址和PORT
  2. 创建套接字,为套接字绑定地址信息,服务端开始监听请求
  3. 开始接收客户端请求
  4. 用一个字符串req接收浏览器的请求信息
  5. 按照http响应信息格式定义首行first、头部header、空白行blank、正文body
  6. 将响应信息发送给用户
  7. 关闭套接字
//http\_srv.cpp
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include <sstream>
using namespace std;

int main(int argc, char\* argv[])
{
	if (argc != 3)
	{
		cout << "请按格式输出 ./http\_srv ip port" << endl;
		return -1;
	}
	//ip地址
	string ip = argv[1];
	//端口号
	uint16_t port = stoi(argv[2]);
	
	//创建套接字
	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(ip.c\_str());
	addr.sin_port = htons(port);
	socklen_t srv_len = sizeof(addr);
	int ret = bind(fd, (struct sockaddr\*)&addr, srv_len);
	if (ret < 0)
	{
		perror("bind");
		return -1;
	}
	//服务端开始监听
	ret = listen(fd, 5);
	if (ret < 0)
	{
		perror("listen");
		return -1;
	}
	while (1)
	{
		//接收客户端请求
		struct sockaddr_in cli_addr;
		socklen_t cli_len;
		int cli_fd = accept(fd, (struct sockaddr\*)&cli_addr, &cli_len);
		if (cli_fd < 0)
		{
			perror("accept");
			continue;
		}
		//用于接收http响应信息
		string req;
		char tmp[4096] = {0};
		ret = recv(cli_fd, tmp, 4096, 0);
		if (ret <= 0)


![img](https://img-blog.csdnimg.cn/img_convert/c039a7257a9bf2e4b007ce692bd4186f.png)
![img](https://img-blog.csdnimg.cn/img_convert/3b8bbd5389728533b64140652abc357f.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

)]
[外链图片转存中...(img-3OKRAR8g-1715887073771)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值