Linux网络:应用层协议http/https

news2024/11/23 7:10:39

认识URL

URL是我们平时说的网址

eg:http常见的URL
http://user:pass@www.example.jp:80/dir/index.htm?uid=1#ch1

注意:

  1. 服务器地址就是域名,相当于服务器ip地址

  2. 像http服务绑定80端口号,https服务绑定443端口。ssh服务端口绑定22号端口。所以只要知道使用的是http协议就知道使用的是80端口。所以这个也可以省略。

  3. 服务文件地址:就是想要获得的资源(视频,图片,网页等)在服务器的路径

  4. ?后查询字符串,是这次http请求的参数。是客户端与服务器之间传递数据的一种方式,多个参数之间用&连接

  5. 片段标识符:当浏览网页时,点击下一张图片,网页不刷新。此时片段标识符一直在更新。

urlencode与urldecode

像 / 与 ?这些特殊字符在URL中的特殊符号时,URL会将这些关键字特殊处理

URL会将这些关键字进行转义,将需要转码的字符转化为16进制,然后从右到左取4位,不足4位直接处理,再每2位做一位前加上%,编码成%XY的形式

1.http协议

http协议是基于请求与响应的应用层协议(cs / bs 模式)

一次http请求包括客户端向服务器request请求,服务器向客户端response响应

http协议 请求格式

常规情况下,http(s)下层传输层协议使用的是tcp协议。

下面用C++ 实现服务器,启动浏览器访问这个服务。将浏览器发送给服务器的request请求打印出来分析http客户端请求的格式

#include<stdlib.h>
#include<iostream>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<cstring>
#include<sys/wait.h>

int main(){
  int listen_sock=socket(AF_INET,SOCK_STREAM,0);
  if(listen_sock<0){
    std::cerr<<"socket error"<<std::endl;
    return 1;
  }

  struct sockaddr_in local;
  memset(&local,0,sizeof(local));

  local.sin_family=AF_INET;
  local.sin_port=htons(8081);
  local.sin_addr.s_addr=INADDR_ANY;

  if(bind(listen_sock,(struct sockaddr*)&local,sizeof(local))<0){
    std::cerr<<"bind error"<<std::endl;
    return 2;
  }

  if(listen(listen_sock,5)<0){
    std::cerr<<"listen error"<<std::endl;
    return 3;
  }

  sockaddr_in client;
  while(true){
    socklen_t len=sizeof(client);
    int sock=accept(listen_sock,(struct sockaddr*)&client,&len);
    if(sock<0){
      std::cout<<"accept error"<<std::endl;
      continue;
    }

    if(fork()==0){
      if(fork()>0){
        exit(0);
      }
      close(listen_sock);
      //读取客户端请求
      char buff[1024];
      size_t size=recv(sock,buff,sizeof(buff)-1,0);
      buff[size]='\0';
      std::cout<<"################http begin#####################"<<std::endl;
      std::cout<<buff<<std::endl;

      exit(0);
    }
    close(sock);
    waitpid(-1,nullptr,0);
  }
  return 0;
}

客户端向服务器发送请求

服务器打印http请求

分析上面的打印结果 

 这一行叫做:请求行

此外,像这些key:value代表了这次请求的若干属性

eg:
User-Agent:发起这次请求的浏览器的信息

这部分叫做:请求报头 

综上http协议格式为:


http协议 响应格式 

当客户端读取到空行时,代表客户端已经读取完http响应报头了。

注意:

  • 客户端向服务器发送请求http时首行带的http版本是客户端的http版本。服务器接受到请求报头时,识别http版本,用对应的http版本进行处理业务。提高了兼容性

  • 响应报头中的状态码:表示服务器处理请求的情况,常见的状态码有200(OK)、404(Not Found)等


http协议方法(GET 、POST)

http GET方法:

http POST方法: 

对比两种请求的请求报头可以发现POST方法比GET方法多了
Content-Length项

GET方法:

  1. 直接获取资源信息
  2. GET方法可以带参数,参数在URL?后面都是GET的参数,通过URL传递给服务器

POST方法:

通过正文提交数据给服务器,不通过URL

http在读取正文时如果此时是POST方法

空行的下一行就是正文,根据Content-Length项可以知道应该在正文上读取几个字节。通过这种方法(POST+Content-Length)就可以有效的读取http正文(请求或响应)


C++实现服务器响应 观察http响应,以及POST 、GET传参

简单的html网页index.html

<html>
  <header><h5>log in<h5><header>
  <body>
    <form method="GET" action="/s">
      user:<br>
      <input type="text" name="user">
      <br>
      password:<br>
      <input type="text" name="passowrd">
      <br>
      <input type="submit" value="register">
  <body>
</html>
#include<string>
#include<stdlib.h>
#include<iostream>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<cstring>
#include<sys/wait.h>

#include<fstream>

int main(){
  int listen_sock=socket(AF_INET,SOCK_STREAM,0);
  if(listen_sock<0){
    std::cerr<<"socket error"<<std::endl;
    return 1;
  }

  struct sockaddr_in local;
  memset(&local,0,sizeof(local));

  local.sin_family=AF_INET;
  local.sin_port=htons(8081);
  local.sin_addr.s_addr=INADDR_ANY;

  if(bind(listen_sock,(struct sockaddr*)&local,sizeof(local))<0){
    std::cerr<<"bind error"<<std::endl;
    return 2;
  }

  if(listen(listen_sock,5)<0){
    std::cerr<<"listen error"<<std::endl;
    return 3;
  }

  sockaddr_in client;
  while(true){
    socklen_t len=sizeof(client);
    int sock=accept(listen_sock,(struct sockaddr*)&client,&len);
    if(sock<0){
      std::cout<<"accept error"<<std::endl;
      continue;
    }

    if(fork()==0){
      if(fork()>0){
        exit(0);
      }
      close(listen_sock);
      //读取客户端请求
      char buff[1024];
      size_t size=recv(sock,buff,sizeof(buff)-1,0);
      buff[size]='\0';
      std::cout<<"################http begin#####################"<<std::endl;
      std::cout<<buff<<std::endl;
#define PAGE "index.html"
      std::ifstream in(PAGE);
      if(in.is_open()){
        in.seekg(0,std::ios::end);//获取文件末尾指针
        size_t size=in.tellg();
        in.seekg(0,std::ios::beg);//定位到文件开头
        char*file=new char[size];
        in.read(file,size);
        in.close();
  //      std::cout<<file<<std::endl;
        std::string statusLine="http/1.1 200 OK\n";
        //响应报头
        std::string respon="Content-Length: "+std::to_string(size);
        respon+="\n";
        std::string blank="\n";//空行
        send(sock,statusLine.c_str(),statusLine.size(),0);
        send(sock,respon.c_str(),respon.size(),0);
        send(sock,blank.c_str(),blank.size(),0);


        //发送正文
        send(sock,file,size,0);
        delete[]file;
      }
      exit(0);
    }
    close(sock);
    waitpid(-1,nullptr,0);
  }
  return 0;
}

首先是GET方法 由上图可知GET方法通过URL项服务器传参。密码和账号都暴露出来了不太好        

其次是POST方法

由上图可知POST通过正文传参,没有直接暴露到URL上,相对比较隐秘一些(并不安全)。

当在http请求时,每次请求之间没有任何关系(无状态)


http响应状态码

常见的状态码为:
200(OK) ,404(Not Found) ,403(Forbidden) ,302(重定向) ,504(Bad Gateway)等等

其中重定向分为临时重定向(307/http1.1 - 302/http1.0)和永久重定向(301)
本质区别:
影响客户端标签,决定客户端是否需要更新目标地址。


http 常用 Header

location:搭配3XX状态码实现重定向
重定向的实现还需要搭配响应报头location:字段

std::string statusLine="http/1.1 307 Temporary Redirect\n";
//响应报头
std::string respon="Content-Length: "+std::to_string(size);
respon+="\n";
respon+="location: https://www.baidu.com/\n";
std::string blank="\n";//空行
send(sock,statusLine.c_str(),statusLine.size(),0);
send(sock,respon.c_str(),respon.size(),0);
send(sock,blank.c_str(),blank.size(),0);

 

 

  • Content-Type: 资源类型(html、text等)
  • Content-Length:正文长度
  • Host:所请求的资源在那个主机那个端口上(代理服务器常用)
  • User-Agent:用户的操作系统以及浏览器版本信息
  • referer:当前页面是从那个页面跳转的,方便回退
  • Cookie:用于在客户端储存少量信息,实现会话(session)的功能

在登录网站时,如果曾经使用过账号密码,第二次登录网站时不需要再次输入账号密码进行身份认证了。

注意:Cookie文件分为内存级和文件级

如果重启客户端还需要输入用户信息的属于内存级,反之就为文件级

  • Connection:长链接keep-alive


2.https协议 

同理对端再收到报文时要先经过SSL或TLS进行解密,再传到应用层

其中加密分为对称加密(异或加密)(密钥负责加密解密)与非对称加密(RSA)(公钥加密,私钥解密)

其中非对称加密 私钥是不对外公开的,公钥可以公开。

 

 

 

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2118735.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EasyCVR无法启动并报错“error while loading shared libraries”,如何解决?

安防监控/视频汇聚平台EasyCVR视频管理系统以其强大的拓展性、灵活的部署方式、高性能的视频能力和智能化的分析能力&#xff0c;为各行各业的视频监控需求提供了优秀的解决方案。通过简单的配置和操作&#xff0c;用户可以轻松地进行远程视频监控、存储和查看&#xff0c;满足…

Python操作ES集群API(增删改查等)

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 学习B站博主教程笔记&#xff1a; 最新版适合自学的ElasticStack全套视频&#xff08;Elk零基础入门到精通教程&#xff09;Linux运维必备—Elastic…

Vue组件:插槽的使用

在实际开发中&#xff0c;子组件往往只提供基本的交互功能&#xff0c;而内容是有父组件来提供的。为此&#xff0c;Vue.js 提供了一种混合父组件内容和子组件模板的方式&#xff0c;这种方式称为内容分发。 1、基本用法 Vue.js 参照当前 Web Components 规范草案实现了一套内…

和 InternLM 解锁“谁是卧底”新玩法

本文来自社区投稿&#xff0c;作者LangGPT联合发起人、东北大学在读博士生王明 在大模型技术日益普及的今天&#xff0c;AI 的应用已经渗透到各个领域&#xff0c;带来了无数创新和乐趣。今天&#xff0c;我们将一起探索如何搭建一个 AI 版的“谁是卧底”游戏。通过 InternStud…

【Unity基础】Input中GetAxis和GetAxisRaw的区别

一句话描述&#xff1a;GetAxis使用了平滑过渡&#xff0c;而GetAxisRaw是直接改变。 在Unity中&#xff0c;Input.GetAxisRaw 和 Input.GetAxis 都用于获取输入设备的轴向输入&#xff08;例如键盘、鼠标或手柄的摇杆&#xff09;&#xff0c;但它们的工作方式和返回值有细微…

GPU 服务器性能评估:多维度深度探索

在深度学习的浩瀚宇宙中&#xff0c;GPU 服务器犹如一颗璀璨的星辰&#xff0c;以其无与伦比的计算能力和效率引领着技术进步的浪潮。为了充分挖掘这一强大工具的潜力&#xff0c;我们需深入探寻其性能评估的奥秘&#xff0c;这不仅仅是对单一指标的简单堆砌&#xff0c;而是从…

从虚拟现实到元宇宙:Facebook引领未来社交的下一步

随着科技的迅猛发展&#xff0c;社交媒体正在经历一场深刻的变革。从最初的文本和图片交流&#xff0c;到如今的沉浸式虚拟现实&#xff08;VR&#xff09;和即将到来的元宇宙&#xff0c;社交互动的方式正在发生根本性的变化。作为行业领军者&#xff0c;Facebook&#xff08;…

3GPP协议入门——物理层基础(一)

1. 频段/带宽 NR指定了两个频率范围&#xff0c;FR1&#xff1a;通常称Sub 6GHz&#xff0c;也称低频5G&#xff1b;FR2&#xff1a;通常称毫米波&#xff08;Millimeter Wave&#xff09;&#xff0c;也称高频5G。 2. 子载波间隔 NR中有15kHz&#xff0c;30kHz&#xff0c;6…

数据库类型有哪些?

根据存储方式的不同&#xff0c;数据库可以分为不同种类。每种类型的数据库&#xff0c;都有各自使用场景以及不同的产品。 ​ 关系型数据库 关系型数据库&#xff08;RDBMS&#xff09;基于关系模型&#xff0c;通过表&#xff08;Table&#xff09;的形式来组织数据&#xf…

利士策分享,如何规划多彩的大学生活?

利士策分享&#xff0c;学习规划多彩的大学生活 踏入大学&#xff0c;如同开启一场充满未知与可能的旅程。 为了让这段旅程不仅充满学术的熏陶&#xff0c;还洋溢着生活的多彩与人际的和谐&#xff0c;我们需要精心规划&#xff0c;积极行动。 一、多彩规划&#xff1a;点亮大学…

双指针的运用

一、双指针 双指针 常⻅的双指针有两种形式&#xff0c;⼀种是对撞指针&#xff0c;⼀种是左右指针。 1.1 对撞指针&#xff1a;⼀般⽤于顺序结构中&#xff0c;也称左右指针。 • 对撞指针从两端向中间移动。⼀个指针从最左端开始&#xff0c;另⼀个从最右端开始&#xff…

一文揭秘:从零开发一套中小型医院的云HIS系统,需要多少开发成本?

从零开发一套中小型的云HIS&#xff08;医院信息系统&#xff09;系统&#xff0c;首先要组建团队&#xff0c;包括招聘、培训、设备购置&#xff0c;然后要经历需求分析、系统设计、编码、测试等多个阶段&#xff0c;这会消耗大量的时间&#xff0c;其开发成本会受到多种因素的…

《凡人歌》重塑现实主义爆款,正午阳光终于“杀”回来了

2024年的现实主义爆款&#xff0c;出自正午阳光之手。 今年剧集市场一个明显的变化在于&#xff0c;最贴近时代生活、最有“爆款潜质”的现实主义题材电视剧的缺位。根据云合数据&#xff0c;截止到2024年9月&#xff0c;年榜前十中没有一部现实主义大剧&#xff0c;古装剧却多…

在线编程实现!如何在Java后端通过DockerClient操作Docker生成python环境

目录 在线编程实现&#xff01;如何在Java后端通过DockerClient操作Docker生成python环境 一、为什么要用后端程序操作Docker 二、安装Docker 1、安装Docker 2、启动Docker 三、DockerClient与CMD操作Docker的区别 四、干货&#xff01;如何使用DockerClient实现在线编程…

通过信息架构提升商业智能:实现数据驱动创新的策略与方法

拥抱数据驱动时代 在当前的数字化转型浪潮中&#xff0c;数据已成为企业最重要的资产之一。全球范围内的网络巨头通过精细的数据管理和分析&#xff0c;已成功颠覆了传统行业。这些企业的成功不仅源于他们掌握了大量数据&#xff0c;还因为他们能有效地利用这些数据来做出精准…

研一小白读论文记录,计算机视觉,Transformer

论文是IEEE收录的一篇论文《CrossFormer: A Versatile Vision Transformer Hinging on Cross-Scale Attention》&#xff08;《基于跨尺度自注意力机制的多功能视觉Transformer》&#xff09; 泛读完之后最大的感悟有以下几点&#xff1a; 1、文章在实验的结果中呈现了大量的…

Getty Images推AI训练样本:3750张高质量照片免费开放

近日&#xff0c;全球领先的商业图库Getty Images发布了一项重大决策&#xff0c;宣布将为AI开发者提供一份包含3750张高分辨率照片的免费训练数据集。这份详尽的数据集覆盖了商业、教育、医疗健康、运动健身、物品物体、插图图标等15个不同领域&#xff0c;目的在于助力AI技术…

unity UGUI高性能飘字解决方案(对象池+合并网格)

本方案仅供参考 从需求出发 游戏类型&#xff1a;微信小游戏 帧数限定&#xff1a;60 已知的几种方案&#xff1a; 1:场上只存在一个mesh&#xff0c;每帧把所有字绘制到一个mesh。 优点&#xff1a;每帧都重绘&#xff0c;高度定制化&#xff0c;可以随意添加、删除。 …

HTTP状态码解析:在Haskell中判断响应成功与否

在互联网的世界里&#xff0c;HTTP状态码是服务器与客户端之间通信的一种语言。它们告诉我们请求是否成功&#xff0c;或者遇到了什么问题。在进行网络编程时&#xff0c;正确地解析和处理这些状态码是至关重要的。本文将探讨HTTP状态码的基本概念&#xff0c;并展示如何在Hask…

KUKA中级学习4:修改软件中机器人名字,纠正示教器时间,下载备份文件进示教器

这里写目录标题 一、修改机器人名字1.1、程序安装下载二、示教器时间修改2.1、时间修改&#xff0c;示教器全英文显示三、下载备份文件 一、修改机器人名字 1.1、程序安装下载 选下面这个 二、示教器时间修改 2.1、时间修改&#xff0c;示教器全英文显示 三、下载备份文件 …