了解HTTP和HTTPS协议

本文详细介绍了HTTP协议的引入、基本特征、URL编码解码、HTTP构成、方法、状态码及其保证方式,还涉及了简单的HTTP服务器实现及HTTPS的安全考量。深入浅出地讲解了对称加密与非对称加密在HTTPS中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HTTP的引入

在当今社会我们已经离不开网络了,基本上我们随时随地都能上网,那你知道上网的实质是干啥吗?
其实很简单:我们做的所有互联网行为都是两种操作:

  1. 把服务器上的数据拿下来。
  2. 把自己的数据传到服务器上去。

当然上网必不能缺少HTTP协议了,我们知道了HTTP是位于应用层的协议,接下来让我们具体来学习HTTP的内容吧!

HTTP基本特征

  1. 无连接 :TCP建立连接和http式无关的,http直接向对方发送http request即可。
  2. 无状态 :http本身是无状态的,并不会记录任何用户信息,记录你的基本信息的技术是cookie + session
  3. 简单快速 : 短链接进行文本传输(http/1.0) 长连接(http/1.1)

认识URL

平时我们所说的“网址”,指的就是URL,是用来定位互联网上的资源的,通常以路径的形式展现(资源所处的路径)。
在这里插入图片描述

urlencode和urldecode

这俩的作用相当于编码和解码。

因为像 / ? :这样的字符会被url当作特殊意义理解。因此这些字符不能随意出现。
要是某个参数中需要带有这些字符,那就必须对这些特殊字符进行转义

转义的规则如下:
将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式
例:
在这里插入图片描述

HTTP构成结构图解:

在这里插入图片描述

HTTP请求: 对照图解理解更深
首行: [方法] + [url] + [版本]

  • Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束
  • Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个Content-Length属性来标识Body的长度;

HTTP响应:
首行: [版本号] + [状态码] + [状态码解释]

  • Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表示Header部分结束
  • Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个
  • Content-Length属性来标识Body的长度; 如果服务器返回了一个html页面, 那么html页面内容就是在
    body中.

HTTP的方法:

在这里插入图片描述
其中最长用的就是GET方法和POST方法:
两者的区别:

  • 在都传参的情况下,GET通过url传参,POST通过正文传参。 因此POST比GET更私密
  • GET传参内容有限,POST理论上可以传更多的参数

HTTP状态码:

在这里插入图片描述
HTTP常见的Header

  • Content-Type: 数据类型(text/html等)
  • Content-Length: Body的长度
  • Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上;
  • User-Agent: 声明用户的操作系统和浏览器版本信息;
  • referer: 当前页面是从哪个页面跳转过来的;
  • location: 搭配3xx状态码使用, 告诉客户端接下来要去哪里访问;
  • Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能

HTTP 状态性的保证

由于http是无状态的,所以用户体验会极差,因此需要维护用户的体验感,那么是怎样做的呢??下面我们看图理解一下:

cookie的作用:
在这里插入图片描述
当然我们要是只用cookie,这个对于用户来说是不安全的,因为当服务器会将用户的信息发送回来,这样其实就相当于你的私密信息在网上“裸奔”,你的私密信息极容易被恶意窃取。那么有没有相对安全的技术呢??下面我们来具体介绍:

cookie+session(相对安全)
在这里插入图片描述

这样在传输的时候只是sid暴漏在外面,你的信息存储在服务器中,当然服务器的安全性肯定要比我们自身的浏览器要高!!!

一个简单的http服务器

实现一个最简单的HTTP服务器, 只在网页上输出 “hello world”;

// httpSever.hpp
#pragma once 

#include<iostream>
#include<string>
#include<unistd.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<signal.h>
#include<strings.h>

#define BACKLOG 5 
using namespace std;
class httpSever{
  private:
    int port;
    int lsock;

  public:
    httpSever(int _p)
      :port(_p),lsock(-1)
    {}
    void InitSever()
    {
      lsock=socket(AF_INET,SOCK_STREAM,0);
      if(lsock < 0)
      {
        cerr<<"socket error!!"<<endl;
        exit(2);
      }
      struct sockaddr_in local;
      bzero(&local,sizeof(local));
      local.sin_family=AF_INET;
      local.sin_port=htons(port);
      local.sin_addr.s_addr=htonl(INADDR_ANY);

     if( bind(lsock,(struct sockaddr*)&local,sizeof(local))< 0)
     {
        cerr<<"bind error!!"<<endl;
        exit(3);
     }
     if(listen(lsock,BACKLOG)< 0)
     {
       cerr<<"listen error!!"<<endl;
       exit(4);
     }
    }
    void server(int sock)
    {
      char request[2048];
      ssize_t s=recv(sock,request,sizeof(request),0);// 假设一次能读完一次请求
      if(s>0){
        request[s]=0;
        cout<<request<<endl;
		// 构建响应	
        string response="HTTP/1.0 200 OK\r\n"; //响应行
        response +="Content-type: text/html\r\n";  // 响应报头
        response +="\r\n"; //空行
        response +="<!DOCTYPE html>\  //一个网页
          <html>\
          <head>\
          <title>guokk</title>\
          </head>\
          <body>\
          <h1>Welcome</h1>\
          <p>hellow world</p>\
          </body>\
          </html>";
        send(sock,response.c_str(),response.size(),0);
      }
      close(sock);
    }
    void start()
    {
      signal(SIGCHLD,SIG_IGN);
      struct sockaddr_in peer;
      for(;;)
      {
        socklen_t len=sizeof(peer);//len每次都要求
        int sock=accept(lsock,(struct sockaddr*)&peer,&len);
        if(sock<0)
        {
          cerr<<"accept error!!"<<endl;
          continue;
        }
        cout << "get a new connect ..."<< endl;
        if(fork()==0)
        {
          close(lsock);
          server(sock);
          exit(0);
        }
        close(sock);
      }
    }
    ~httpSever()
    {
      if(lsock!=-1)
        close(lsock);
    }
};

//##################################
// httpSever.cc
#include"httpSever.hpp"

void Usage( string proc )
{
  cout<<"Usage \n\t";
  cout<<proc << " port "<<endl;
}
int main(int argc,char*argv[])
{
  if(argc !=2)
  {
    Usage(argv[0]);
    exit(1);
  }
  httpSever*hp= new httpSever(atoi(argv[1]));
      hp->InitSever();
      hp->start();

      delete hp;
      return 0;
}

结果展示:

在这里插入图片描述
在这里插入图片描述

HTTPS

https和http 都是超文本传输,但是https有很多安全性考量,因此https会比http慢。
在这里插入图片描述

对称加密和非对称加密

  • 对称加密
    在这里插入图片描述

  • 非对称加密
    在这里插入图片描述
    那么有的人就会问了,为什么并不直接通过非对称加密传输数据呢??而是费那么大的劲把对称加密的密钥传输过去??
    原因很简单:因为非对称加密采用的算法复杂,效率较低,而非对称加密的效率高。

  • 中间服务器监听问题
    在这里插入图片描述

由于服务器被监听所以有两个问题必须解决:

  1. 如何防止中间信息被篡改的问题?

    数据摘要+数据签名技术
    在这里插入图片描述

  2. 远端服务器的身份认证问题?(怎么保证你访问的服务器是合法的)
    在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值