10.王道_HTTP

1. 互联网时代的诞生


2. HTTP的基本特点

2.1客户端-服务端模型

2.2 无状态协议

2.3 可靠性

2.4 文本协议

3. HTML,CSS和JS


4. HTTP的各个组件

4.1 客户端

4.2 服务端

4.3 代理




5. URI和URL



6. HTTP报文

  • HTTP报文分为两种------请求报文和响应报文。

6.1 GET请求示例





  • 注意:C++中的类不用调用c中的mem_系列函数 来处理。

  • 单线程阻塞服务端

cpp 复制代码
#include <54func.h>

#include <iostream>
#include<string>

using std::cerr;
using std::string;


class HttpServer
{
public:
    HttpServer(const string &ip,unsigned short port)
        :_ip(ip),_port(port)
    {}

    ~HttpServer()
    {
        if(_sockfd>0)
        {
            close(_sockfd);// 注意这里不需要作用域限定符号,而bind需要,因为std中也有bind函数
        }
    }

    void start();

    void recvAndShow();
private:
    string _ip;
    unsigned short _port;
    int _sockfd;
};

void HttpServer::start()
{
    _sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(_sockfd < 0)
    {
        perror("socket");
        exit(1);
    }

    int reuse = 1;
    int ret = setsockopt(_sockfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse));
    if(ret < 0)
    {
        perror("setsockfd");
        exit(1);
    }
    struct sockaddr_in serverAddr;
    memset(&serverAddr,0,sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(_port);
    serverAddr.sin_addr.s_addr = inet_addr(_ip.c_str());

    ret = ::bind(_sockfd,(struct sockaddr*)&serverAddr,sizeof(serverAddr));
    if(ret < 0)
    {
        perror("bind");
        exit(1);
    }

    listen(_sockfd,10);
}

void HttpServer::recvAndShow()
{
    while(true)
    {
        int netfd = ::accept(_sockfd,nullptr,nullptr);
        char buf[4096] = {0};
        ssize_t sret = recv(netfd,buf,sizeof(buf),0);
        printf("sret = %ld,buf = %s\n",sret,buf);
        close(netfd);
    }
}

int main()
{
    HttpServer server("10.102.1.35",1234);
    server.start();
    server.recvAndShow();


    return 0;
}

6.2 POST请求示例





6.3 请求报文详解

方法

路径


版本

  • 1.0和1.1的区别
  • HTTP2.0是二进制协议不是文本协议,典型的应用场景是grpc

首部字段

  • Content-Length,因为TCP是一个流式协议,需要使用类似于我们的火车头协议。包的长度。

  • Host:域名,处理一个IP对应多个域名的情况

  • Connection:长连接或者短连接

  • user-agent:客户端的类型

  • MIME

    • 本质就是文件类型
    • 格式:大类型/小类型:text/html,text/css,text/javascript

请求体

6.4 响应报文


响应的状态

  • 200 ok
  • 300配合浏览器生效,重定向
  • 404找不到
  • 403 客户端有错误
  • 500 服务器有错误
cpp 复制代码
#include <54func.h>

#include <iostream>
#include<string>

using std::cerr;
using std::string;


class HttpServer
{
public:
    HttpServer(const string &ip,unsigned short port)
        :_ip(ip),_port(port)
    {}

    ~HttpServer()
    {
        if(_sockfd>0)
        {
            close(_sockfd);// 注意这里不需要作用域限定符号,而bind需要,因为std中也有bind函数
        }
    }

    void start();

    void recvAndShow();
    string response();
private:
    string _ip;
    unsigned short _port;
    int _sockfd;
};

void HttpServer::start()
{
    _sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(_sockfd < 0)
    {
        perror("socket");
        exit(1);
    }

    int reuse = 1;
    int ret = setsockopt(_sockfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse));
    if(ret < 0)
    {
        perror("setsockfd");
        exit(1);
    }
    struct sockaddr_in serverAddr;
    memset(&serverAddr,0,sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(_port);
    serverAddr.sin_addr.s_addr = inet_addr(_ip.c_str());

    ret = ::bind(_sockfd,(struct sockaddr*)&serverAddr,sizeof(serverAddr));
    if(ret < 0)
    {
        perror("bind");
        exit(1);
    }

    listen(_sockfd,10);
}

void HttpServer::recvAndShow()
{
    while(true)
    {
        int netfd = ::accept(_sockfd,nullptr,nullptr);
        char buf[4096] = {0};
        ssize_t sret = recv(netfd,buf,sizeof(buf),0);
        printf("sret = %ld,buf = %s\n",sret,buf);

        string repo = response();
        send(netfd,repo.c_str(),repo.size(),0);

        close(netfd);
    }
}

int main()
{
    HttpServer server("10.102.1.35",1234);
    server.start();
    server.recvAndShow();


    return 0;
}
string HttpServer::response()
{
    string startLine = "HTTP/1.1 200 ok\r\n";
    string headers = "Server: MyHttpServer\r\n";
    string body = "<html>Hello World!</html>";
    headers+="Content-Type: text/html \r\n";
    headers+="Content-Length" + std::to_string(body.size()) + "\r\n";
    string emptyLine = "\r\n";
    return startLine+headers+emptyLine+body;



}

浏览器直接下载

  • 重定向

7. RESTful的设计风格

目的:HTTP接口用起来像对象的方法调用

幂等性

  • 重复发请求,对结果有无影响。
  • get,delete,put是幂等的。
  • post增加是不幂等的。

8. HTTPs的原理

8.1 对称加密和非对称加密


8.2 TLS的实现机制

  • 两个步骤
  • 1.非对称加密(引入证书机关)
    1. 对称加密

XML

tinyxml2

cpp 复制代码
#include <iostream>
#include"tinyxml2.h"

using namespace tinyxml2;

int main()
{
    XMLDocument doc;
   doc.LoadFile("test.xml");

   XMLElement *root = doc.FirstChildElement("sites");

   for(XMLElement *site = root->FirstChildElement("site"); site != nullptr; site=site->NextSiblingElement("site"))
   {
       XMLElement *name = site->FirstChildElement("name");
       XMLElement *url = site->FirstChildElement("url");
       std::cerr<<"name:"<<name->GetText() <<",url:"<<url->GetText()<<std::endl;
   }
    return 0;
}

构建的代码


解析的代码

Json解析

简介

nlohmann/json的使用

  • nlohmann/json是一个header-only的C++ json解析库,可以用于构造和解析JSON对象。

  • 键值必须是字符串

  • 数据-》字节流:序列化/编码
  • 字节流-》数据:反序列化。解码
json 复制代码
{
    "sites":
    [
        {

            "site":
            {
                "name":"王道论坛",
                "url":"www.baidu.com"
            }
        },
        {

            "site":
            {
                "name":"google",
                "url":"www.google.com"
            }
        },
        {

            "site":
            {
                "name":"微博",
                "url":"www.weibo.com"
            }
        }
    ]
}

序列化

cpp 复制代码
#include <iostream>
#include <nlohmann/json.hpp>
using Json = nlohmann::json;
int main(){
        Json sites1 =
        {
            {
                "sites",
                {
                        {{"name", "王道论坛"}, {"url", "www.cskaoyan.com"}},
                        {{"name", "google"}, {"url", "www.google.com"}},
                        {{"name", "微博"}, {"url", "www.weibo.com"}}
                }
            }
        };
        Json sites2;
        sites2["sites"].push_back({{"name", "王道论坛"}, {"url",
                                                  "www.cskaoyan.com"}});
        sites2["sites"].push_back({{"name", "google"}, {"url", "www.google.com"}});
        sites2["sites"].push_back({{"name", "微博"}, {"url", "www.weibo.com"}});
        Json object;
        object["key1"] = "value1";
        object["key2"] = 2;
        // 使用[]运算符可以增加键值对
        // 使用push_back方法可以增加数组元素
        std::cout << sites1.dump() << "\n";
        std::cout << sites2.dump() << "\n";
        std::cout << object.dump() << "\n";
}

反序列化

cpp 复制代码
#include <iostream>
#include<nlohmann/json.hpp>
using Json = nlohmann::json;
int main() {
        std::string json_string = R"(
        {
             "sites":
              [
                { "name":"王道论坛" , "url":"www.cskaoyan.com" },
                { "name":"google" , "url":"www.google.com" },
                { "name":"微博" , "url":"www.weibo.com" }
              ]
        })";
        // 解析JSON字符串
        Json sites = Json::parse(json_string);
        // 遍历站点信息并打印
        for (const auto& site : sites["sites"]) {
            std::cout << "Name: " << site["name"] << ", URL: " << site["url"] <<std::endl;
            //另一种写法
            //std::cout << "Name: " << sites["sites"][i]["name"] << ", URL: " <<
            //  sites["sites"][i]["url"] << std::endl;
        }
return 0;
}
相关推荐
O。o.尊都假都6 小时前
UDP协议
linux·服务器·网络·网络协议·udp
2501_916013747 小时前
从一次被抄袭经历谈起:iOS App 安全保护实战
websocket·网络协议·tcp/ip·http·网络安全·https·udp
无锡耐特森7 小时前
ProfiNet与CANopen:新能源时代的“语言翻译官”
网络·网络协议
一代...8 小时前
【计网】TCP/IP四层模型(一)
网络协议·tcp/ip·智能路由器
鸿蒙布道师11 小时前
鸿蒙NEXT开发动画案例2
android·ios·华为·harmonyos·鸿蒙系统·arkui·huawei
00后程序员张11 小时前
做 iOS 调试时,我尝试了 5 款抓包工具
websocket·网络协议·tcp/ip·http·网络安全·https·udp
I烟雨云渊T11 小时前
iOS 模块化开发流程
ios
猴子请来的逗比48912 小时前
http重新为https
网络协议·学习·http·https
wang090712 小时前
网络协议之DHCP和PXE分析
网络·arm开发·网络协议