Lesson11:http协议
前言

- 应用层:就是程序员基于socket接口之上编写的具体逻辑,做了很多工作,都是和文本处理有关的--- 协议分析与处理
- http协议,一定会具有大量的文体分析和协议处理


- 如果用户想再url中包含url本身用来作为特殊字符的字符,url形式的时候,浏览器会自动给我们进行编码encode
- 一般服务端收到之后,需要进行转回特殊字符
快速构建http请求和响应的报文格式

HttpServer.cc
#include <iostream>
#include <memory>
#include <cassert>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#include "HttpServer.hpp"
#include "Usage.hpp"
#include "Util.hpp"// 一般http都要有自己的web根目录
#define ROOT "./wwwroot" // ./wwwroot/index.html
// 如果客户端只请求了一个/,我们返回默认首页
#define HOMEPAGE "index.html"void HandlerHttpRequest(int sockfd)
{// 1. 读取请求 for testchar buffer[10240];ssize_t s = recv(sockfd, buffer, sizeof(buffer) - 1, 0);if (s > 0){buffer[s] = 0;// std::cout << buffer << "--------------------\n" << std::endl;}std::vector<std::string> vline;Util::cutString(buffer, "\n", &vline);std::vector<std::string> vblock;Util::cutString(vline[0], " ", &vblock);// 拿到请求行std::string file = vblock[1];// cilent想要的文件名std::string target = ROOT;if(file == "/") file = "/index.html";target += file;std::cout << target << std::endl;// 打开这个文件,再从这个文件中拿数据std::string content;std::ifstream in(target);if(in.is_open()){std::string line;while(std::getline(in, line)){content += line;}in.close();}std::string HttpResponse;if(content.empty()) {HttpResponse = "HTTP/1.1 404 NotFound\r\n";}else {HttpResponse = "HTTP/1.1 200 OK\r\n";}HttpResponse += "\r\n";HttpResponse += content;// 2. 试着构建一个http的响应send(sockfd, HttpResponse.c_str(), HttpResponse.size(), 0);
}int main(int argc, char *argv[])
{if (argc != 2){Usage(argv[0]);exit(0);}std::unique_ptr<HttpServer> httpserver(new HttpServer(atoi(argv[1]), HandlerHttpRequest));httpserver->Start();return 0;
}
HttpServer.hpp
#pragma once#include <iostream>
#include <signal.h>
#include <functional>
#include "Sock.hpp"class HttpServer
{
public:using func_t = std::function<void(int)>;// 包装器->函数
private:int listensock_;// 监听uint16_t port_;Sock sock;// 套接字func_t func_;
public:HttpServer(const uint16_t &port, func_t func): port_(port),func_(func){listensock_ = sock.Socket();sock.Bind(listensock_, port_);// 绑定sock.Listen(listensock_);// 监听}void Start(){signal(SIGCHLD, SIG_IGN);// 解决父进程需要进程等待的问题for( ; ; ){std::string clientIp;uint16_t clientPort = 0;int sockfd = sock.Accept(listensock_, &clientIp, &clientPort);if(sockfd < 0) continue;if(fork() == 0){close(listensock_);func_(sockfd);close(sockfd);exit(0);}close(sockfd);}}~HttpServer(){if(listensock_ >= 0) close(listensock_);}
};
Log.hpp
#pragma once#include <iostream>
#include <cstdio>
#include <cstdarg>
#include <ctime>
#include <string>// 日志是有日志级别的
#define DEBUG 0
#define NORMAL 1
#define WARNING 2
#define ERROR 3
#define FATAL 4const char *gLevelMap[] = {"DEBUG","NORMAL","WARNING","ERROR","FATAL"
};#define LOGFILE "./calculator.log"// 完整的日志功能,至少: 日志等级 时间 支持用户自定义(日志内容, 文件行,文件名)
void logMessage(int level, const char *format, ...)
{
#ifndef DEBUG_SHOWif(level== DEBUG) return;
#endifchar stdBuffer[1024]; //标准部分time_t timestamp = time(nullptr);snprintf(stdBuffer, sizeof stdBuffer, "[%s] [%ld] ", gLevelMap[level], timestamp);char logBuffer[1024]; //自定义部分va_list args;va_start(args, format);vsnprintf(logBuffer, sizeof logBuffer, format, args);va_end(args);FILE *fp = fopen(LOGFILE, "a");fprintf(fp, "%s%s\n", stdBuffer, logBuffer);fclose(fp);
}
makefile
HttpServer:HttpServer.ccg++ -o $@ $^ -std=c++11 -lpthread.PHONY:clean
clean:rm -f HttpServer
Sock.hpp
#pragma once#include <iostream>
#include <string>
#include <cstring>
#include <cerrno>
#include <cassert>
#include <unistd.h>
#include <memory>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <ctype.h>
#include "Log.hpp"class Sock
{
private:const static int gbacklog = 20;public:Sock() {}// 创建套接字int Socket(){int listensock = socket(AF_INET, SOCK_STREAM, 0);if (listensock < 0){logMessage(FATAL, "create socket error, %d:%s", errno, strerror(errno));exit(2);}logMessage(NORMAL, "create socket success, listensock: %d", listensock);return listensock;}// 绑定void Bind(int sock, uint16_t port, std::string ip = "0.0.0.0"){struct sockaddr_in local;memset(&local, 0, sizeof local);local.sin_family = AF_INET;local.sin_port = htons(port);inet_pton(AF_INET, ip.c_str(), &local.sin_addr);if (bind(sock, (struct sockaddr *)&local, sizeof(local)) < 0){logMessage(FATAL, "bind error, %d:%s", errno, strerror(errno));exit(3);}}// 监听void Listen(int sock){if (listen(sock, gbacklog) < 0){logMessage(FATAL, "listen error, %d:%s", errno, strerror(errno));exit(4);}logMessage(NORMAL, "init server success");}// 一般经验// const std::string &: 输入型参数// std::string *: 输出型参数// std::string &: 输入输出型参数int Accept(int listensock, std::string *ip, uint16_t *port){struct sockaddr_in src;socklen_t len = sizeof(src);int servicesock = accept(listensock, (struct sockaddr *)&src, &len);if (servicesock < 0){logMessage(ERROR, "accept error, %d:%s", errno, strerror(errno));// 转移return -1;}if(port) *port = ntohs(src.sin_port);if(ip) *ip = inet_ntoa(src.sin_addr);return servicesock;}// 连接bool Connect(int sock, const std::string &server_ip, const uint16_t &server_port){struct sockaddr_in server;memset(&server, 0, sizeof(server));server.sin_family = AF_INET;server.sin_port = htons(server_port);server.sin_addr.s_addr = inet_addr(server_ip.c_str());if(connect(sock, (struct sockaddr*)&server, sizeof(server)) == 0) return true;else return false;}~Sock() {}
};
Usage.hpp
#pragma once#include <iostream>
#include <string>void Usage(std::string proc)
{std::cout << "\nUsage: " << proc << " port\n" << std::endl;
}
Util.hpp
#pragma once#include <iostream>
#include <vector>class Util
{
public:// aaaa\r\nbbbbb\r\nccc\r\n\r\n// 按sep分割符,分割字符static void cutString(std::string s, const std::string &sep, std::vector<std::string> *out){std::size_t start = 0;while (start < s.size()){auto pos = s.find(sep, start);if (pos == std::string::npos) break;std::string sub = s.substr(start, pos - start);// std::cout << "----" << sub << std::endl;out->push_back(sub);start += sub.size();start += sep.size();}if(start < s.size()) {out->push_back(s.substr(start));}}
};

HTTP协议格式
HTTP请求

- get方法通过url传参,回显输入的私密信息,不够私密
- post方法通过正文提交参数,不会回显,一般私密性是有保证的
- 注: 私密性不是安全,加密和解密才是安全
- Connection: keep-alive 长连接
- Connection:close 短连接
HTTP响应

HTTP的状态码



- 301是永久重定向,302和307是临时重定向
会话管理


- http的特征:1.简单快速,2.无连接,3.无状态
- 虽然http没有状态,但是tpc套接字是有状态的
- 在我们使用网站并登上账号的时候,cookie会记录我们的信息,并通过算法形成唯一的ID
HTTPS协议介绍


- HTTPS实际就是在应用层和传输层协议之间加了一层加密层(SSL&TLS),
- 这层加密层本身也是属于应用层的,它会对用户的个人信息进行各种程度的加密。
- HTTPS在交付数据时先把数据交给加密层,由加密层对数据加密后再交给传输层。
对称加密 vs 非对称加密
- 采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密。
- 采用公钥和私钥来进行加密和解密,用其中一个密钥进行加密就必须用另一个密钥进行解密,这种加密方法称为非对称加密
各种加密方案




MITL攻击

CA证书
当服务端申请CA证书的时候,CA机构会对该服务器进行审核,并专门为该网站形成数字签名,过程如下
- CA机构拥有非对称加密的私钥A和公钥A`
- CA机构对服务端申请的证书明文数据进行hash,形成数据摘要
- 然后对数据摘要用CA私钥A`加密,得到数字签名S
非对称加密 + 对称加密 + CA认证


相关文章:
Lesson11:http协议
前言 应用层:就是程序员基于socket接口之上编写的具体逻辑,做了很多工作,都是和文本处理有关的--- 协议分析与处理http协议,一定会具有大量的文体分析和协议处理如果用户想再url中包含url本身用来作为特殊字符的字符,url形式的时候,浏览器会自动给我们进行编码encode一般服务端…...
计算机信息安全有哪些SCI期刊推荐? - 易智编译EaseEditing
以下是计算机信息安全方向的SCI期刊推荐: IEEE Transactions on Information Forensics and Security 该期刊主要发表信息安全和数字取证方面的原创性研究,包括数据安全、网络安全、身份认证、加密、信息隐藏等领域的研究成果。该期刊的影响因子为8.134…...
CNVD-2023-12632 泛微e-cology9 sql注入 附poc
目录 漏洞描述影响版本漏洞复现漏洞修复 漏洞描述 泛微 E-Cology9 协同办公系统是一套基于 JSP 及 SQL Server 数据库的 OA 系统,包括知识文档管理、人力资源管理、客户关系管理、项目管理、财务管理、工作流程管理、数据中心等打造协同高效的企业管理环境&#…...
赛宁网安合作伙伴大会成功举办,重磅发布SCBaaS服务!
3月29日,“赛宁网安合作伙伴大会”在江苏南京隆重举办。大会现场汇集网络安全数字化领域的专业人才、技术专家,共同研讨数字安全发展趋势,分享智能安全解决方案和技术创新产品。 会上,赛宁网安产品专家针对数字化靶场、网络安…...
R语言 4.2.2安装包下载及安装教程
[软件名称]:R语言 4.2.2 [软件大小]: 75.6 MB [安装环境]: Win11/Win10/Win7 [软件安装包下载]: https://pan.quark.cn/s/b6f604930d04 R语言软件的GUI界面比较的简陋,只有一个命令行窗口,且每次创建图片都会跳出一个新的窗口,比较的繁琐,我们可以安装RStudio,来更方便的操作R(…...
快速玩转 CNStack 2.0 流量防护
作者:冠钰 云原生下的服务治理 在云原生技术的演进过程中,依托云原生技术能力,形成一个可以向下管理基础设施,向上管理业务应用的技术中台,越来越成为企业期望的云原生技术落地趋势。随着云原生技术中台 CNStack 发布…...
你还在用原生 poi 处理 excel?太麻烦了来瞧瞧这个
1、easypoi 前言 Excel 在日常工作中经常被用来存储用例信息,是一种非常便捷的数据存储工具有着众多的优点,我们就不一一介绍了。 今天来讲讲 Java 操作 Excel,总所周知 Java 是世界上最好的语言(不容反驳)ÿ…...
No.027<软考>《(高项)备考大全》【第11章】项目风险管理
【第11章】项目风险管理1 章节相关1.1 考试相关1.2 ITO口诀2 章节概述2.1 风险的含义2.2 风险定义的三个必要条件2.3 项目风险2.4 风险的随机性和相对性2.5 风险的分类2.6 风险成本2.7.1 风险损失有形成本2.7.2 风险损失无形成本2.8 项目风险管理过程3 规划风险管理4 识别风险4…...
mit6.824 lab2c-数据持久化
目录2c简介2b、2a问题测试时间2c简介 简单的说,raft需要将currentTerm、voteFor、entries(当前的所有日志)保存到硬盘进行持久化存储。 保存的方法:在变量改变时,利用persist()中的gob将变量序列化,存储在persister结构体中。&a…...
leaflet使用L.geoJSON加载文件,参数filter的使用方法(127)
第127个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中加载geojson文件,这里介绍filter的使用方法。filter将用于决定是否包含某个功能的函数。 默认是包括所有特征。 直接复制下面的 vue+leaflet源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方…...
23年5月高项学习笔记7—— 质量管理
质量通常指产品质量,也包括工作质量(即过程),产品质量是指产品的使用价值,工作质量是产品质量的保证,反映了产品质量直接相关的工作的对产品质量的保证程度。 公差:结果的可接受范围 项目合同…...
学编程需要哪些基础呢?一起来看看吧
众所周知程序员薪酬高、工作环境好,是很多人向往的职业,那么学编程需要什么基础?0基础能学编程吗? 学编程需要什么基础? 1、数学基础 从计算机发展和应用的历史来看计算机的数学模型和体系结构等都是有数学家提出的&…...
PECS In Java泛型类型通配符限定之<? extends T>与<? super T>
泛型类型通配符限定 🚆PECS | 类型通配符限定如何使用“<? extends T>”和“<? super T>”通配符java源码示例PECS | 类型通配符限定 PECS原则是指在使用泛型时,当我们需要传递一个泛型集合时,如何选择适当的泛型类型通配符来…...
电子招投标系统源码之了解电子招标投标全流程
随着各级政府部门的大力推进,以及国内互联网的建设,电子招投标已经逐渐成为国内主流的招标投标方式,但是依然有很多人对电子招投标的流程不够了解,在具体操作上存在困难。虽然各个交易平台的招标投标在线操作会略有不同࿰…...
admin Tips
1 获取 当前浏览器 url new URL(window.location.href)...
ToBeWritten之Radare2 使用教程
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬…...
实时翻译屏幕插件
程序插件的功能是:点击按钮,将获取屏幕截图,然后翻译输出图片。(目前只支持翻译英语) 要实现这个功能,我们可以使用Python编程语言,结合一些库来完成。以下是一个简单的实现方案: …...
代码随想录算法训练营第二天| 977,209,59
977.有序数组的平方 * 数组平方后,最大值一定是在两侧 因为可以采用双指针 package algor.trainingcamp;import java.util.Arrays;/*** author lizhe* version 1.0* description: https://leetcode.cn/problems/squares-of-a-sorted-array/** 有序数组的平方* 给…...
echarts 地图板块点击着色,移除着色
//选择省份变色 showProvince(name) { this.oldName name; this.mapChart && this.mapChart.dispatchAction({ type: geoSelect, name }) }, //移除上次点击变色 hideProvince() { this.mapChart && this.mapChart.dispatchAction({ type: geoUnSelect, name:…...
Visual Studio Code (vscode)自定义用户代码段快速打出for循环等
比如fori这样的快捷键就打不出代码块了 自定义用户代码块的方法: 工具栏 > 文件 > 首选项 > 用户代码片段 然后在弹出的搜索框中填写javascript.json 有提示 不用打全就行 (会有javascript选中) 打开配置文件javascript.json 这里面显示的就是编写代码块的例子 "…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...
