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

wordpress文章目录树青岛百度快速排名优化

wordpress文章目录树,青岛百度快速排名优化,网站板块设计,昆山建设银行网站首页如果你不能飞,那就跑; 如果跑不动,那就走; 实在走不了,那就爬。 无论做什么,你都要勇往直前。 --- 马丁路德金 --- 从零开始学习http协议 1 什么是http协议2 认识URL3 http的请求和应答3.1 服务端设计…

在这里插入图片描述

如果你不能飞,那就跑;
如果跑不动,那就走;
实在走不了,那就爬。
无论做什么,你都要勇往直前。
--- 马丁·路德·金 ---

从零开始学习http协议

  • 1 什么是http协议
  • 2 认识URL
  • 3 http的请求和应答
    • 3.1 服务端设计
    • 3.2 如何让外界可以访问Linux云服务器
    • 3.3 运行测试
  • 4 理解http请求与应答
    • 4.1 宏观理解
    • 4.2 http请求反序列化

1 什么是http协议

虽然我们说, 应用层协议是我们程序猿自己定的. 但实际上, 已经有大佬们定义了一些现成的, 又非常好用的应用层协议, 供我们直接参考使用。 HTTP(超文本传输协议)就是其中之一。http应用十分的广泛,几乎每一名程序员(无论前后端 无论C++/Java/Go…)都会接触到!

在互联网世界中, HTTP(HyperText Transfer Protocol, 超文本传输协议) 是一个至关重要的协议。 它定义了客户端(如浏览器) 与服务器之间如何通信, 以交换或传输超文本,超文本支持视频,网页 ,图片等等!

HTTP 协议是客户端与服务器之间通信的基础。 客户端通过 HTTP 协议向服务器发送请求, 服务器收到请求后处理并返回响应。 HTTP 协议是一个无连接、 无状态的协议, 即每次请求都需要建立新的连接, 且服务器不会保存客户端的状态信息。

但是有个疑问?http是基于TCP协议的,也就是面向连接的,为什么http确是无连接的协议呢?
因为http会使用Tcp建立的链接,无需再次建立新的链接。就好比之前我们实现的网络计算器,服务端和客户端的连接是通过TCP建立的,但是通信传输Request和Response直接通过Tcp建立的连接即可,无需再次建立连接!

2 认识URL

平时我们浏览的网站:百度 , 哔哩哔哩 ,力扣…等等网站都有一个域名

百度 :https://www.baidu.com/
哔哩哔哩:https://www.bilibili.com/
力扣:https://leetcode.cn/
...

这些网址都是https协议,这些网址其实就是URL!
在这里插入图片描述
访问时会将网址解析成IP地址!一般成熟的协议名称与端口号是强关联的,称之为知名端口号!

  1. HTTP (Hypertext Transfer Protocol):端口号:80 ,用于在Web服务器和客户端之间传输网页。
  2. HTTPS (HTTP Secure):端口号:443, HTTP的安全版本,通过SSL/TLS加密传输数据。
  3. FTP (File Transfer Protocol):
    • 控制端口:21 ,用于文件传输。
    • 数据端口:20,(主动模式)或随机端口(被动模式)
  4. SSH (Secure Shell):端口号:22 ,用于安全地访问远程服务器。

为什么平时访问网站并没有输入端口号?
只有同时具备IP地址和端口号才可以访问到对应的服务器,浏览器发起请求时会自动拼接端口号80!就类似日常生活中报警会自觉想到拨打110 , 火灾会自然的想到拨打119!

通信中离不开“资源”两个字,通信要么是从别处获取资源,要么是向对方发送资源。http协议下的资源是超文本!
网页,图片,音频,视频都是超文本!在进行通信之前,用户想要获取的资源都在后端的云服务器中,云服务器一般都是Linux系统,那么在Linux视角下不就都是文件吗!

为了将这个文件(资源)发给客户端,就必须要找到这个文件,那么怎么找到这个文件呢?当然是通过文件的唯一标识符 — 路径来实现!在URL中后半部分不就是我们的路径吗!这样通过IP地址确定的唯一主机+唯一的路径就可以标识互联网中的唯一的文件资源!

注意第一个斜杠不是Linux服务器的根目录,而是web根目录,web根目录可以是Linux中的任何目录!

所以URL就叫:统一资源定位符

urlencode 和 urldecode

  • 像 / ? : 等这样的字符,已经被 url 当做特殊意义理解了。因此这些字符不能随意出现。比如,某个参数中需要带有这些特殊字符,就必须先对特殊字符进行转义。
  • 转义的规则如下: 将需要转码的字符转为 16 进制, 然后从右到左, 取 4位(不足 4 位直接处理), 每 2 位做一位, 前面加上%,编码成%XY 格式

3 http的请求和应答

3.1 服务端设计

下图是http请求的一个信息:
在这里插入图片描述
接下来我们来通过代码实验,来测试一下是否可以获取到这些信息!
首先我们简化一下代码,在传输层直接进行IO,直接在Socket文件中获取数据流,将线程的函数方法修改为以下形式:

	// 注意设置为静态函数 , 不然参数默认会有TcpServer* this!!!static void *Execute(void *args){pthread_detach(pthread_self()); // 线程分离!!!// 执行Service函数TcpServer::ThreadData *td = static_cast<TcpServer::ThreadData *>(args);// 直接进行IOstd::string reqstr;// 这里默认读取到的是完整的请求ssize_t n = td->_sockfd->Recv(&reqstr);if (n > 0){std::string resstr = td->_this->_service(reqstr);td->_sockfd->Send(resstr);}td->_sockfd->Close();delete td;return nullptr;}

回调函数单独设计一个HttpServer类来获取客户端申请的数据,目前直接进行简单的打印处理就好!

#include <iostream>
#include <string>class HttpServer
{
public:HttpServer(){}std::string HandlerHelperRequest(std::string& Requeststr){std::cout<<"------------------"<<std::endl;std::cout << Requeststr << std::endl;return std::string();//暂时这样}~HttpServer(){}
};

然后ServerMain中,将HandlerHelperRequest作为回调函数构造TcpServer!进行启动即可!那么接下来我们是不是就可以在外界通过IP地址和端口号就可以访问Linux服务器上启动的进程了呢???还不可以,我们需要对Linux云服务器做一些处理,才能让外界成功的访问!

3.2 如何让外界可以访问Linux云服务器

让外界可以访问Linux云服务器需要两步操作:云服务器的安全组设置和服务器操作系统层面的防火墙设置。

云服务器的安全组设置操作步骤如下,这里以阿里云服务器为例:

  1. 首先在控制台中找到安全组,打开需要操作的实例对象
  2. 在实例中手动添加需要使用什么协议开放哪些端口,手动保存即可:
    • 协议类型:选择 TCP
    • 端口范围:填写“8888/8888”或“8888-8888”
    • 授权对象:可以设置为“0.0.0.0/0”以允许所有IP访问,但出于安全考虑,建议限制为您的IP地址或特定IP范围。
      在这里插入图片描述

云服务器设置好时候,接下来就进行服务器操作系统层面的防火墙设置:

  1. 对于CentOS:
    # 查看防火墙状态
    sudo systemctl status firewalld
    # 如果需要,启动防火墙服务
    sudo systemctl start firewalld
    # 检查端口8888是否开放
    sudo firewall-cmd --zone=public --query-port=8888/tcp
    # 如果端口未开放,添加端口规则
    sudo firewall-cmd --zone=public --add-port=8888/tcp --permanent
    # 重新加载防火墙规则
    sudo firewall-cmd --reload
    
  2. 对于Ubuntu:
    # 查看防火墙状态
    sudo ufw status
    # 如果需要,启用ufw
    sudo ufw enable
    # 检查端口8888是否开放
    sudo ufw allow 8888/tcp
    # 如果端口未开放,添加规则
    sudo ufw allow 8888/tcp
    # 重新加载防火墙规则
    sudo ufw reload
    

这样外界就可以通过IP地址和端口访问到对应的进程了!!!

3.3 运行测试

测试之前我们先获取一个当前机器的IP地址:

  1. 使用 curl 命令:
    curl ifconfig.me
    
  2. 使用 wget 命令:
    wget -qO- ifconfig.me
    

都可以获取到机器的外网IP!
我们启动程序,等待外部的链接:
可以通过手机或者电脑的浏览器通过IP地址和端口号来进行访问:
在这里插入图片描述
进行访问之后,会获取到对应的信息:
在这里插入图片描述

可以看到电脑WIndows系统和手机IPhone都成功的访问了我们的服务器!!!非常cool!!!

4 理解http请求与应答

4.1 宏观理解

请求和应答是http协议中双方都认识的结构化数据:

一个基本的http请求的格式是这个样子的,按行为单位!
在这里插入图片描述

  1. 请求行:指出请求类型(如GET或POST)、资源路径和使用的HTTP版本:
    • 方法(Method):表明对资源的请求类型,如 GET(获取资源)、POST(提交数据)、PUT(更新资源)、DELETE(删除资源)等。
    • URI(Uniform Resource Identifier):请求的资源的路径,例如一个网页的地址的后半部分。
    • HTTP版本(HTTP Version):表明使用的HTTP协议版本,如 HTTP/1.1 或 HTTP/2。
  2. 请求报头:提供关于客户端环境和请求本身的信息,如用户代理、接受的内容类型等。其中是以键值对的方式进行存储。
  3. 空行:请求报头和请求正文之间的分隔符。
  4. 请求正文(可选):包含要发送给服务器的数据,如表单数据。

http的应答与请求的格式很类似:在这里插入图片描述

  1. 状态行:包含HTTP版本、状态码和状态消息。例如,HTTP/1.1 200 OK 表示服务器成功处理了请求。
  2. 响应报头:提供关于响应的信息,如内容类型、内容长度、服务器类型、设置Cookie等。例如:
  3. 空行:响应报头和响应正文之间的分隔符。
  4. 响应正文(可选):包含从服务器返回的实际内容,如HTML页面、图片或其他数据。

知道了请求和报文的结构,其本质上还是报文,那么如何将其报头与有效载荷进行分离呢?
我们看到的请求和应答的结构可以看到,报头和报文是通过换行符进行分割的!巧了我们之前不也是这样进行操作的吗!而且只要有正文,就会有对应的content-length:xxx来帮我我们判断正文的是否完整!

4.2 http请求反序列化

接下来我们简单设计一下HttpRequesthttp请求的结构化数据!
首先根据其整体的结构我们可以加入四个成员变量:请求行 ,请求报头, 空行 ,请求正文

// 设计http协议
class HttpRequest
{
public:HttpRequest(){}void Serialization(std::string &reqstr){}void Deserialization(std::string &reqstr){}~HttpRequest(){}private:std::string _req_line;                 // 请求行std::vector<std::string> _req_headers; // 请求报头std::string _blank_line;               // 分割行std::string _req_body_text;            // 正文
};

这是最基本的四块数据,我们先对这四部分进行反序列化。因为他们都是根据分隔符\r\n进行分割的字符串,所以十分好处理:

std::string GetLine(std::string &reqstr){// 寻找分隔符auto pos = reqstr.find(base_sep);if (pos == std::string::npos)return std::string();std::string line = reqstr.substr(0, pos);if (line.empty())return base_sep;// 在原字符串中删除reqstr.erase(0, base_sep.size() + line.size());return line;}void Deserialization(std::string &reqstr){// 进行反序列化_req_line = GetLine(reqstr);//请求行do{std::string header = GetLine(reqstr);if (header == "")break;else if (header == base_sep)break;else_req_headers.push_back(header);} while (true);//请求报头_blank_line = GetLine(reqstr);//空行_req_body_text = GetLine(reqstr);//请求正文}

这样就可以将一个字符串切分为四个部分了:
在这里插入图片描述
接下来我们可以对数据进行进一步处理:我们加入更加具体的成员变量

		std::string _method; //请求方法std::string _url; //请求路径std::string _version;//版本std::unordered_map<std::string , std::string> _kv_headers;//报头

处理很简单:按照字符串结构编写代码即可!

 void ParseReqLine(){// 优雅的操作!!!std::stringstream ss(_req_line);ss >> _method >> _url >> _version;}void ParseReqHeader(){for (auto &header : _req_headers){auto pos = header.find(line_sep);if (pos == std::string::npos)continue;std::string k = header.substr(0, pos);std::string v = header.substr(pos + line_sep.size());if (k.empty() || v.empty())continue;_kv_headers.insert(std::make_pair(k, v));}}void Deserialization(std::string &reqstr){// 进行反序列化//...//----------------具体数据的处理-------------------ParseReqLine();   // 请求行的处理!!!ParseReqHeader(); // 处理报头}

我们可以将结果打印出来看看:

在这里插入图片描述
非常好,我们成功将reqstr进行了反序列化,之后我们再来实现业务逻辑的代码!!!

后续文章,敬请期待!

http://www.hrbkazy.com/news/9660.html

相关文章:

  • 网业进不去什么原因湖州网站seo
  • b2c跨境电商潍坊seo按天收费
  • 广州网站建设品牌怎么交换友情链接
  • 宁夏银川做网站的公司视频app推广
  • 肥乡邯郸做网站网络公司seo教程
  • 简单网站建设报价单百度指数趋势
  • 西乡网站建设中国seo高手排行榜
  • 金昌网站seo全球搜
  • 客户做网站一定报价怎么办网站策划书怎么写
  • 徐州公司建站模板中国企业100强
  • 公司做网站比较好的中视频自媒体平台注册官网
  • 网站制作吧十大搜索引擎排名
  • 招聘网站比对表怎么做3d建模培训学校哪家好
  • 济南网站建设要多少钱国产最好的a级suv88814
  • 可做长图的网站网络推广外包注意哪些
  • 科技网站设计案例成人技术培训班有哪些种类
  • 如何查看网站关键词郑州网站策划
  • 网站开发过程会遇到的问题怎么制作网页页面
  • 山东钢结构建设局网站seo文章代写一篇多少钱
  • java做网站的软件网络营销论文5000字
  • 做数码后期上数码网站武汉网络推广公司排名
  • 南京网站做的好的公司免费google账号注册入口
  • 网站制作完成后广告联盟广告点击一次多少钱
  • 张家口建设委员会网站为什么不建议去外包公司上班
  • 网站建设公司发展前景培训机构网站设计
  • 做网站报价明细表网站设计制作教程
  • 广州哪家网站建设公司好交换友情链接的渠道有哪些
  • 域名访问wordpress小图标不显示seo自动推广工具
  • 网站源码大全免费的湖南网站优化
  • 四平公司做网站北京网站seo技术厂家