当前位置: 首页 > news >正文

Linux网络-HttpServer的实现

文章目录

  • 前言
  • 一、请求报文的解析
    • URL的解析
  • 二、响应报文的发送
    • Content-Lenth
    • Conten-Type
    • Cookie和Set-Cookie
      • Cookie的风险
  • 三、尝试发送一个HTML网页
    • 404网页
    • Location 重定向
  • 四、浏览器的多次请求行为
  • 总结


前言

之前我们简单理解了一下Http协议,本章我们将在LInux下使用Socket编程自主完成一个HttpServer。 可以做到接收Http报文数据,加以解析再向远端发送Http报文数据。


之前写过很多遍的网络套接字编程代码就不再重复写了,这里直接写关于HttpServer的代码

一、请求报文的解析

上一章我们讲了,请求报文主要分为 请求行,请求报头,请求正文。
在这里插入图片描述
所以,我们就需要来解析我们收到的报文数据。

class HttpRequest
{
public:HttpRequest(){}bool Deserialize(std::string &request){size_t pos = request.find(sep);if (pos == std::string::npos){// 不完整报文lg(Warning, "Recv Incomplete Request...");return false;}_request_line = request.substr(0, pos);request.erase(0, pos + sep.size());std::string tmp;while (true){pos = request.find(sep);if (pos == std::string::npos){break;}tmp = request.substr(0, pos);if (tmp.empty()){// 说明已经截到空行break;}_request_header.push_back(tmp);request.erase(0, pos + sep.size());}request.erase(0, sep.size());_content = request;return true;}bool Parse(){std::string tmp = _request_line;int pos = tmp.find(blank);if (pos == std::string::npos){// 解析的请求行存在问题return false;}_function = tmp.substr(0, pos);tmp.erase(0, pos + blank.size());pos = tmp.find(blank);if (pos == std::string::npos){// 解析的请求行存在问题return false;}std::string url_tmp = tmp.substr(0, pos);if (url_tmp == "/"){_url = homepage;}else{_url = fileroot;_url += url_tmp;}tmp.erase(0, pos + blank.size());_http_version = tmp;return true;}public:std::string _request_line;std::vector<std::string> _request_header;std::string _content;std::string _function;std::string _url;std::string _http_version;bool _isFound = true; //判断是否存在访问资源
};

上面通过的request成员函数,可以讲一份完整的报文全部解析下来。

URL的解析

上章我们讲过,URL的作用是为了找到该服务器上唯一的资源,那么我们就需要对URL再进行解释,才能正确找到想要请求的文件。

一般来讲我们的,我们在网址上的URL其实是在服务器的工作目录中的查找的,当然,如果你想访问其他目录的文件,只需要自己稍作解析即可,我们仅谈论大多数情况。
所以,为了可以更好的控制访问资源,我们就可以在服务器工作目录创建一个web根目录,将所有需要用到的其他资源分类放进去。
在这里插入图片描述
就比如说这里,我们创建了一个名为webroot的根目录。
在这里插入图片描述
再在服务器内部代码定义根目录路径,后续只需要直接在后面添加我们解析后的URL字符串就可以实现精准访问唯一一份资源了。

std::string ReadFileData(const std::string &filepath)
{std::ifstream in(filepath, std::ios::binary);if (!in.is_open()){// 文件打开失败,返回一个空串lg(Warning, "File Open Failed...");return "";}// 将文件流指针移动到文件结尾in.seekg(0, std::ios_base::end);auto len = in.tellg();// 重新将文件流指针移动到文件开头in.seekg(0, std::ios_base::beg);std::string content;content.resize(len);in.read((char *)content.c_str(), content.size());return content;
}

因为我们有时候会读取一个二进制文件,例如png,jpg格式的图片,所以我们这里采用二进制读取的方式打开文件。

最后返回的content就是文件的全部数据。

二、响应报文的发送

在上章我们也讲过相应报头是由 状态行,响应报头,正文组成。
在这里插入图片描述
所以,我们要遵循http协议,就必须要遵守http协议的响应报头发送格式来发送数据。

    std::string Encode(const std::string &content, const HttpRequest &hr){std::string mes;if (hr._isFound){mes += "HTTP/1.0 200 OK\r\n";}else{mes += "HTTP/1.0 404 NotFound\r\n";}mes += "Content-Lenth: ";mes += std::to_string(hr._content.size());mes += sep;mes += "Content-Type: ";mes += SuffixtoType(hr._suffix);mes += sep;mes += "Set-Cookie: ";mes += hr._content;mes += sep;mes += sep; // 空行mes += content;return mes;}

该Encode函数就帮我们格式化了一个还算完整的响应报文。

Content-Lenth

Content-Lenth 作为响应报头很重要的一部分,它标识了响应报文中正文的字符长度,浏览器也会去解析Content-Lenth来读取正文部分。

Conten-Type

Conten-Type 作为相应报头很重要的一部分,它标识了响应报文中正文数据是一个怎样的类型,是一个html格式的网页?是一个png格式的图片…

并且http协议对于不同后缀的文件都有一个标识字符串,如下例
在这里插入图片描述

Cookie和Set-Cookie

当我们的响应报头携带了Set-Cookie: xxxxxxxxxx 数据后,并被浏览器读取到了,浏览器就会生成一个Cookie文件,里面存放你的Cookie信息。以后你再去访问该域的网页,浏览器就会自动在请求报头携带上你的Cooke: xxxxxxxxxx。

这就是为什么我们在登录一些视频网站之后,只需要登陆一次,下次登录就不需要我再输入账号密码了。这就是因为浏览器保存了你的Cookie登录信息。

Cookie的风险

这种便利的功能也一般会带来风险,如果有黑客入侵你的计算机,获取了你的Cookie信息,将你的Cookie信息粘贴到黑客他自己的浏览器中,他就能以你的身份浏览网站。

为了降低风险,许多互联网公司采用的都是session ID的方式来作为Cookie内容保存,将你的私人信息保存到远端,这样即使黑客获取你的Cookie信息,也没办法获取到你的隐私信息。

虽然如今的互联网已经十分成熟,已经有了很多的安全策略,但是还是有可能通过非法获取你的Cookie信息来冒用你的身份。

降低此类情况的发生我们就需要做到:不随便点陌生网址并输入你的账号密码; 在不常用的计算机记得删除你的Cookie信息; 收到异常登录的邮件即使修改账号密码。

三、尝试发送一个HTML网页

通过URL,我们已经可以准确访问到服务器的一个资源,现在我们在这份资源上随便写一份简单的HTML代码

在这里插入图片描述
在这里,我们先打开我们的服务器,绑定好自己的端口号。
在这里插入图片描述
我上面那朵花的文件位于服务器的web根目录下的/html/first_page.html位置。
在这里插入图片描述
我们的浏览器是成功的获取到了/html/first_page.html的内容,也识别解析了html。


再从我们的抓包软件来看
在这里插入图片描述
我们可以看到浏览器收到的响应报文的正文正是我们的first_page.html原封不动的内容。

404网页

在这里插入图片描述
http的响应报文中的状态码是有规定的,像我们刚刚成功发送了一个完整的响应报文,我这里设置的状态码就是200 ,描述就是OK。

而对于我们经常看到的404,其实代表的就是没有找到你想要访问的那份资源,即你所访问的资源不存在。

这里我也是自己写一一个简单的404网页,大家可以来看看效果。
在这里插入图片描述
抓包到的响应报文
在这里插入图片描述

Location 重定向

Location在http协议当中是作为一个重定向的报头数据,后面携带上一个网址,即可直接重定向到另一个网址去。

不过需要注意的是,Location还必须配合状态码,需要状态码为3xx,我们这里采用临时重定向,所以就使用的302状态码。

在这里插入图片描述

那么我们是否会直接跳转到bilibili的主页去呢?
在这里插入图片描述
从结果来看我们是直接跳转到了b站的。

四、浏览器的多次请求行为

一般我们访问像百度,淘宝这些大网页,里面的内容是形形色色的,包含各种图片视频。 而对于现在的我们来看来,这些无非都是文件,是保存在服务器的web根目录下的文件。

那么,像这种大网站内容极其丰富,我们仅仅通过一次请求和响应可以将所有的资源全部获取吗?

答案肯定是不能的,因为图片是文件,视频是文件,html网页也是文件,而html语言作为前端网页开发语言,就可以与浏览器进行“联动”。

在这里插入图片描述
例如href标签可以让我们的网页进行跳转,跳转就需要再次对我们的服务器发起二次请求。

在这里插入图片描述
img标签可以添加图片,而浏览器识别到 src,也需要再次发起请求来获取图片。

在这里插入图片描述
在这里插入图片描述
最后对于favicon.ico的请求是网站图标的获取。
这里就可以看出,我访问一次带有图片的网页,它是给我们提交了不仅仅一次的请求的。


总结

本章学习了如何搭建一个建议的httpServer,并通过浏览器进行访问。

下一章我们将学习https协议。

相关文章:

Linux网络-HttpServer的实现

文章目录 前言一、请求报文的解析URL的解析 二、响应报文的发送Content-LenthConten-TypeCookie和Set-CookieCookie的风险 三、尝试发送一个HTML网页404网页Location 重定向 四、浏览器的多次请求行为总结 前言 之前我们简单理解了一下Http协议&#xff0c;本章我们将在LInux下…...

GPT-4o的综合评估与前景展望

如何评价GPT-4o? GPT-4o作为OpenAI推出的最新一代大型语言模型&#xff0c;其性能、功能和应用前景都备受关注。以下是对GPT-4o的综合评估与前景展望&#xff1a; 一、技术性能评估 响应速度&#xff1a;GPT-4o在响应速度上有了显著提升&#xff0c;能够在极短的时间内对输入…...

私人云盘(自动云同步)

一、项目简介 模仿小米的云服务&#xff0c;实现一个通过TCP实现的私人云盘&#xff0c;因为能力有限&#xff0c;所以只实现自动云同步这一个功能&#xff0c;具体可以分为三个小功能&#xff0c;即保持云端和终端数据一致、实现文件的上传与下载以及手动同步 二、涉及到的知…...

【CMake】Linux 下权限丢失与软链接失效问题

【CMake】Linux 下权限丢失与软链接失效问题 文章目录 【CMake】Linux 下权限丢失与软链接失效问题问题概述解决方法1 - 安装目录2 - 安装文件3 - 手动指定 使用 Linux 下原生命令行注意事项参考链接 问题概述 一般使用 CMake 安装&#xff0c;在 Windows 平台不会出问题&…...

内部类介绍

内部类&#xff08;Inner Class&#xff09;是在另一个类的内部定义的类。它可以访问外部类的所有成员&#xff0c;包括私有成员。内部类有两种主要形式&#xff1a;局部内部类&#xff08;定义在方法内部&#xff09;和成员内部类&#xff08;定义在类的内部&#xff0c;但不在…...

【CVPR2021】LoFTR:基于Transformers的无探测器的局部特征匹配方法

LoFTR&#xff1a;基于Transformers的局部检测器 0. 摘要 我们提出了一种新的局部图像特征匹配方法。我们建议先在粗略级别建立像素级密集匹配&#xff0c;然后再在精细级别细化良好匹配&#xff0c;而不是按顺序进行图像特征检测、描述和匹配。与使用成本体积搜索对应关系的密…...

总结一下 C# 如何自定义特性 Attribute 并进行应用

前言 Attribute&#xff08;特性&#xff09;是一种用于为程序元素&#xff08;如类、方法、属性等&#xff09;提供元数据信息的方法。 特性是一种声明式的信息&#xff0c;附加到程序元素上&#xff0c;提供额外的数据用于描述和控制这些元素的行为。 在编译和运行时&…...

三种暴露方法和引入方式

1.分别暴露 export ...export...用于按需导出一个或多个模块&#xff0c;在导入时需要使用花括号指定导入的模块名称&#xff0c;例如import { a, b } from module module.js中 export let a 1 export function b(){console.log(hello,vue) } 2.统一暴露 export { ...}用于统…...

“Git之道:掌握常用命令,轻松管理代码“

目录 1. 初始化和配置 2. 提交和更新 3. 分支和合并 4. 查看和比较 5. 远程仓库 6. 文件操作命令 1. 初始化和配置 git init&#xff1a;在当前目录初始化一个新的Git仓库git config&#xff1a;配置Git的全局或局部选项git clone&#xff1a;从远程仓库克隆一个本地副本…...

Linux vim 文本编辑 操作文本 三种模式

介绍 vi 是一个经典的行编辑器&#xff0c;支持模式编辑&#xff08;包括普通模式、插入模式和命令模式&#xff09;。 vim 保留vi核心功能的基础上&#xff0c;增加了多级撤销、语法高亮、插件支持等高级功能。 两者的最大区别&#xff0c;简单的来说vim就是vi的增强版 三…...

JavaFX DatePicker

JavaFX DatePicker允许从给定日历中选择一天。DatePicker控件包含一个带有日期字段和日期选择器的组合框。JavaFX DatePicker控件使用JDK8日期时间API。 import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.DatePicker; import j…...

开展“安全生产月”活动向媒体投稿的好方法找到了

作为一名单位的信息宣传员,我的职责是确保每一次重要活动的声音都能准确无误地传达到社会的每一个角落。在这样的使命驱动下,我曾一度陷入了一种传统的投稿模式——依赖电子邮件,将精心准备的稿件一封封地发送给各大媒体。初入此行,我满心以为这便是信息传播的路径,却未料到,这…...

商讯杂志商讯杂志社商讯编辑部2024年第10期目录

案例分享 基于胜任素质的干部选拔和梯队建设体系探讨——以A区卫生健康系统为例 康文雁; 1-4 “家庭五险一金”对居民商业保险购买存在挤出效应——基于江苏省徐州、淮安、泰州三市的实证研究 李炳毅; 5-8 人口老龄化背景下促进徐州市经济高质量发展的探究 李艳秋;…...

在VS Code中快速生成Vue模板的技巧

配置vue.json: { "Print to console": {"prefix": "vue","body": ["<template>"," <div class\"\">\n"," </div>","</template>\n","<scri…...

新火种AI|Sora发布半年之后,AI视频生成领域风云再起

作者&#xff1a;一号 编辑&#xff1a;美美 AI视频最近有些疯狂&#xff0c;Sora可能要着急了。 自OpenAI的Sora发布以来&#xff0c;AI视频生成技术便成为了科技界的热门话题。尽管Sora以其卓越的性能赢得了广泛关注&#xff0c;但其迟迟未能面向公众开放&#xff0c;让人…...

《UNIX环境高级编程》第三版(电子工业出版社出品)——两年磨一剑的匠心译作

历时两年&#xff0c;《UNIX环境高级编程》的翻译工作终于落下帷幕。这一路走来&#xff0c;真可谓是如鱼饮水&#xff0c;冷暖自知。还记得最初看到招募译者消息的那一刻&#xff0c;内心的激动难以言表。我毫不犹豫地报名&#xff0c;而后经历了试译、海选等激烈的角逐&#…...

【RK3588/算能/Nvidia智能盒子】AI“值守”,规范新能源汽车充电站停车、烟火及充电乱象

近年来&#xff0c;中国新能源汽车高速发展&#xff0c;产量连续8年位居全球第一。根据中国充电联盟数据&#xff0c;截至2023年6月&#xff0c;新能源汽车保有量1620万辆&#xff0c;全国充电基础设施累计数量为665.2万台&#xff0c;车桩比约2.5:1。 虽然新能源汽车与充电桩供…...

使用ReentrantLock和ThreadPoolExecutor模拟抢课

这里主要是在场景下帮助理解ReentrantLock和线程池的使用。 import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class GrabCourseTask implements Runnable {private final String studentName;private static int availableS…...

VirtFuzz:一款基于VirtIO的Linux内核模糊测试工具

关于VirtFuzz VirtFuzz是一款功能强大的Linux内核模糊测试工具&#xff0c;该工具使用LibAFL构建&#xff0c;可以利用VirtIO向目标设备的内核子系统提供输入测试用例&#xff0c;广大研究人员可以使用该工具测试Linux内核的安全性。 工具要求 1、Rust&#xff1b; 2、修补的Q…...

统计学一(术语,正态)

目录 一&#xff0c;常用术语 二&#xff0c;正态分布&#xff08;Normal Distribution&#xff09; 三&#xff0c;中心极限定理(Central Limit Theorem) 一&#xff0c;常用术语 population(族群)&#xff1a;要统计的总的 populationSize(族群数量)&#xff1a;要统计的总…...

CleanMyMac X for Mac系统优化垃圾清理软件卸载 工具(小白轻松上手,简单易学)

Mac分享吧 文章目录 效果一、准备工作二、开始安装1、双击运行软件&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、启动台显示软件图标&#xff0c;表示安装成功 三、运行测试1、打开软件&#xff0c;配置2、授权&#xff0c;允许完全磁盘访问 安装完成&a…...

从0开始开发一个简单web界面的学习笔记(HTML类)

文章目录 什么是HTML页面vscode 开放工具搭建第一个HTML页面编写vscode 如何快速生成代码框架html标签——注释、标题、段落、换行标签格式化标签img 标签(src 属性01)img 属性02(alt、title、width/height、border)a标签href属性a标签target属性表格标签01 基本属性表格标签02…...

【机器学习】对大规模的文本数据进行多标签的分类处理

1. 引言 1.1. NLP研究的背景 随着人工智能技术的飞速发展&#xff0c;智能助手、聊天机器人和虚拟客服的需求正呈现出爆炸性增长。这些技术不仅为人们提供了极大的生活便利&#xff0c;如日程管理、信息查询和情感陪伴&#xff0c;还在工作场景中显著提高了效率。聊天机器人凭…...

C++之std::type_identity

目录 1.简介 2.C20的std::type_identity 3.使用 type_identity 3.1.阻止参数推导 3.1.1.模板参数推导过程中的隐式类型转换 3.1.2.强制显式实例化 3.2.阻止推断指引 3.3.类型保持 3.4.满足一些稀奇古怪的语法 4.示例 5.总结 1.简介 std::type_identity 是 C17 引入的…...

头歌资源库(10)拼数字

一、 问题描述 二、算法思想 初始化一个长度为10的数组count&#xff0c;用于记录卡片中每个数字的数量。 从1开始依次尝试拼出正整数&#xff0c;直到无法拼出下一个数为止。 对于每个尝试拼出的正整数&#xff0c;遍历其每一位的数字&#xff0c;检查该数字在count中是否还…...

虚谷数据库-定时作业

虚谷数据库提供定时作业机制&#xff0c;用于定时、定期、自动的进行某些操作&#xff0c;可通过系统包 dbms_scheduler 进行定时作业创建、调度、查看、删除等。 DBMS_SCHEDULER 系统包封装了以下过程/函数&#xff1a;ENABLE、DISABLE、SET_JOB_ARGUMENT_VALUE、DROP_JOB、R…...

AWD攻防比赛流程手册

AWD简单介绍&#xff1a; AWD&#xff1a;Attack With Defence&#xff0c;即攻防对抗&#xff0c;比赛中每个队伍维护多台服务器&#xff08;一般两三台&#xff0c;视小组参赛人数而定&#xff09;&#xff0c;服务器中存在多个漏洞&#xff08;web层、系统层、中间件层等&am…...

Golang的json解析--Gjson库的使用举例

目录 简介 安装 原生的json解析 Gjson使用举例 基本使用 键路径 使用示例 其他资源 简介 在 Golang 中&#xff0c;解析 JSON 数据是一项非常常见的任务。Go提供了标准的JSON包&#xff0c;可以轻松地将JSON数据序列化和反序列化。但是&#xff0c;在使用标准JSON包…...

基于Langchain构建本地大型语言模型(LLM)问答系统的经验分享

基于Langchain构建本地大型语言模型&#xff08;LLM&#xff09;问答系统的经验分享 https://download.csdn.net/download/xziyuan/89334371?spm1001.2101.3001.9500 最近&#xff0c;我一直在探索如何利用Langchain来构建一个本地的大型语言模型问答系统。在这个过程中&…...

对抗式生成模仿学习(GAIL)

目录 1 预先基础知识 1.1 对抗生成网络&#xff08;GAN&#xff09; 1.1.1 基本概念 1.1.2 损失函数 1.1.2.1 固定G&#xff0c;求解令损失函数最大的D 1.1.2.2 固定D&#xff0c;求解令损失函数最小的G 1.2 对抗式生成模仿学习特点 2 对抗式生成模仿学习&#xff08;…...

网站宣传海报图片/seo推广系统排名榜

一. 简介 1. 锁定义 锁是计算机协调多个进程或线程并发访问某一资源的机制。 在数据库中&#xff0c;除了传统的计算资源&#xff08;如CPU、RAM、I/O等&#xff09;的争用以外&#xff0c;数据也是一种供需要用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数…...

同ip怎么做不同的网站/品牌公关公司

特点: 有序重复,包括null,通过整数索引访问 实现类ArrayList和LinkedList ArrayList--动态数组 不线程同步 单线程合适 List<String> nListnew ArrayList<String>();nList.add("A");nList.add("B");nList.add("C");nList.add(1, …...

wordpress 主题腾讯cdc/温州seo优化公司

目录版本整形数组浮点型数组嵌套列表构成的多维数组&#xff0c;内层的列表被当作二维数组的行创建一个长度为10的数组&#xff0c;数组的值都是0创建一个长度为10的数组&#xff0c;数组的值都是1创建一个35的浮点型数组&#xff0c;数组的值都是3.14创建一个数组&#xff0c;…...

马云为什么做网站/文明seo

Enumable类型是linq to object 是一个很特殊的类型 这个类型的数据源都是在程序的内存中 Queryable类型是 Linq to sql 对数据库进行操作都是这个类型 这个类型会生成表达式目录树 方法体只能有一行代码 Expression 表达式目录树 ///外链接 需要用join into …...

如皋做网站的公司/有哪些网络营销公司

一、自主切换IP该模式适合一些需要登陆、Cookie缓存处理等爬虫需要精确控制IP切换时机的业务。 爬虫程序可以通过设置HTTP头Proxy-Tunnel: 随机数&#xff0c; 当随机数相同时,访问目标网站的代理IP相同。例如需要登录,获取数据两个请求在一个IP下,只需对这组请求设置相同Proxy…...

推荐广州微信网站建设/页面设计漂亮的网站

1.选择唯一性索引 唯一性索引的值是唯一的&#xff0c;可以更快速的通过该索引来确定某条记录。例如&#xff0c;学生表中学号是具有唯一性的字段。为该字段建立唯一性索引可以很快的确定某个学生的信息。如果使用姓名的话&#xff0c;可能存在同名现象&#xff0c;从而降低查…...