【网络】:HTTP服务器

HTTP服务器

  • 一.预备知识
  • 二.HTTP的请求和响应
  • 三.写一个简单的HTTP服务器
  • 四.返回响应
  • 五.HTTP方法和状态码

一.预备知识

1.域名

https://www.baidu.com,这是一个域名。在技术角度上,访问一个服务器其实只需要知道它的ip和域名就行了,而域名主要是方便我们进行查看。而域名会经过域名解析器解析为ip。那么端口号呢?其实https的端口号固定是443,http的端口号固定是80,所以在访问时,浏览器会自动加上。

2.url

例如你看到一篇博客很好,分享了链接http://t.csdnimg.cn/2fzXz,像这种链接就被称为url(统一资源定位符),所有网络上的资源都可以通过“字符串”标识并且获取。仔细观察这个url,/是Linux的分隔符,代表它的服务器是Linux,同时也被称为web根目录。

在这里插入图片描述

3.特殊字符

我们在浏览器上都是通过关键字进行搜索的,例如:搜索一个helloword。

在这里插入图片描述

浏览器通过kv的方式进行匹配。但是在我们的搜索词中如果出现了特殊字符,像 / ? : 等这样的字符, 已经被url当做特殊意义理解了,所以为了避免歧义,浏览器就必须先对特殊字符进行转义。

转义的规则如下:

将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式

在这里插入图片描述

“+” 被转义成了 “%2B”

二.HTTP的请求和响应

http请求报文由多行构成。分为请求行,请求报头,请求正文(如果不需要发资源可以不写);每个部分之间用‘\n’或者’\r\n’分割。

请求行:

1.Method:常用的GET和POST。
2.url:请求的资源
3.HTTP version:一般为1.0,1.1或者2.0
4.中间以空格(一般为一个)为分隔符。

请求报头

1.由多行构成。
2.内部大多是key:value结构。
3.内部有一个content length用来记录请求正文的字节数。
4.在请求报头和请求正文之间用一空行表示分离。

在这里插入图片描述

在这里插入图片描述

响应与请求是一样的。

在这里插入图片描述

三.写一个简单的HTTP服务器

由于之前写过sock的封装,这里就直接使用了。这里的服务器是最基本的就不详解了。

HttpServer.hpp

#include "Socket.hpp"


struct ThreadData
{
  int socket;
};

class HttpServer
{
public:
  HttpServer(const uint16_t port=3389):port_(port)
  {}
  ~HttpServer()
  {}

  bool Start()
  {
    listensock_.Socket();
    listensock_.Bind(port_);
    listensock_.Listen();
    while(true)
    {
      std::string clientip;
      uint16_t clientport;
      int sockfd=listensock_.Accept(&clientip,&clientport);
      //创建线程处理任务
      pthread_t tid;
      ThreadData*td=new ThreadData;
      td->socket=sockfd;
      pthread_create(&tid,nullptr,ThreadRun,td);
    }
  }

  static void* ThreadRun(void*args)
  {
    pthread_detach(pthread_self());//执行完毕后,自己释放
    ThreadData*td=static_cast<ThreadData*>(args);
    char buffer[1024];
    ssize_t n=read(td->socket,buffer,sizeof(buffer));
    if(n>0)
    {
      buffer[n]=0;
      std::cout<<buffer<<std::endl;
    }

    close(td->socket);
    delete td;
    return nullptr;
  }
private:
  Sock listensock_;
  uint16_t port_;
};

HttpServer.cc

#include "HttpServer.hpp"


int main(int argc,char*args[])
{
  if(argc>2)
  {
    std::cout<<"参数传递错误"<<std::endl;
    exit(1);
  }
  HttpServer hp;
  hp.Start();
  return 0;
}

Socket.hpp

#pragma once

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

class Sock
{
public:
  Sock()
  {
  }
  ~Sock()
  {
  }
  void Socket()
  {
    socket_ = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_ < 0)
    {
      std::cout << "create socket error!!!" << std::endl;
      exit(1);
    }
  }
  void Bind(uint16_t port,std::string ip="0.0.0.0")
  {
    struct sockaddr_in local;
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_port = htons(port);
    inet_aton(ip.c_str(), &local.sin_addr);

    if (bind(socket_, (struct sockaddr *)&local, sizeof(local)))
    {
      std::cout << "Bind error!!!" << std::endl;
      exit(2);
    }
  }
  void Listen(int backlog = 10)
  {
    if (listen(socket_, backlog) < 0)
    {
      std::cout << "Listen error!!!" << std::endl;
      exit(3);
    }
  }

  int Accept(std::string *clientip, uint16_t *clientport)
  {
    struct sockaddr_in client;
    socklen_t len = sizeof(client);
    int newfd = accept(socket_, (struct sockaddr *)&client, &len);

    if (socket_ < 0)
    {
      std::cout << "Accept error!!!" << std::endl;
      return -1;
    }
    uint16_t port = ntohs(client.sin_port);
    char ip[64];
    inet_ntop(AF_INET, &(client.sin_addr), ip, sizeof(ip));

    *clientip = ip;
    *clientport = port;
    return newfd;
  }

  bool Connect(const std::string &ip, const uint16_t &port)
  {
    struct sockaddr_in peer;
    memset(&peer, 0, sizeof(peer));
    peer.sin_family = AF_INET;
    peer.sin_port = htons(port);
    inet_pton(AF_INET, ip.c_str(), &(peer.sin_addr));

    int n = connect(socket_, (struct sockaddr *)&peer, sizeof(peer));
    if (n == -1)
    {
      std::cerr << "connect to " << ip << ":" << port << " error" << std::endl;
      return false;
    }
    return true;
  }

  int Fd()
  {
    return socket_;
  }

  void Close()
  {
    close(socket_);
  }

private:
  int socket_;
};

makefile

HttpServer:HttpServer.cc
	g++ -o $@ $^ -lpthread -std=c++11
.PHONY:clean
clean:
	rm -f HttpServer

在这里插入图片描述

我们主机收到的请求:

第一行:GET,URL,HTTP版本
HOST:代表的主机。
User-Agent:请求的客户端
中间每一行都是key-value结构

四.返回响应

我们可以根据上面的请求格式构建一个响应。

在这里插入图片描述

在这里插入图片描述

五.HTTP方法和状态码

1.HTTP方法

在这里插入图片描述

在平常的搜索过程中,用户是如何将自己的数据提交给服务器的呢?其实是通过表单,也就是搜索框。如果我们通过get进行提参,那么参数就会自动拼接到url后面。而post方法采用请求正文的方式进行提交。由于get方法会显示在url上,所以post方法更私密。

在这里插入图片描述

2.HTTP状态码

在这里插入图片描述

重点说一下3开头的,重定向就是由于某些原因,服务器无法为我们完成服务,它返回给我们一个新的地址,这个新地址由Location(报头内的数据)指定。这时浏览器就会二次发起请求,去访问新的地址。

在这里插入图片描述

3.报头内常见属性

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

长连接:

这次我们写的http其实是短链接,当进行一次链接后就断开,无疑这样是低效的。所以开发者设计了一种长连接,在进行连接时一次发送多个请求,这样就可以进行多次响应。例如:淘宝的主页就有许多照片,每一张照片都有一个链接,而长连接就可以一次读取多张照片以提高效率。

Cookie

我们在登陆一个APP时,即使关闭了它,在短时间内重新登陆也不需要输入密码,这是因为在浏览器内有一个cookie文件,服务器通过Set Cookie响应,把个人的登陆信息储存在cookie文件内,之后的每一次http请求都会自动携带cookie文件内的内容。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电力物联网系统设计

电力物联网系统设计 简介 在新能源行业从业多年&#xff0c;参与和负责过大大小小的的项目&#xff0c;发电侧、电网侧、用户侧系统都有过实际的项目经验&#xff0c;这些项目或多或少都有物联网采集方面的需求&#xff0c;本篇文章将会对电力行业物联网经验做一个总结分享。 …

LeetCode 刷题 [C++] 第3题.无重复字符的最长子串

题目描述 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 题目分析 可以使用滑动窗口加哈希表来实现&#xff1a; 使用start和end两个变脸来表示滑动窗口的头部位置和尾部位置&#xff0c;两者开始均为0&#xff1b;借助哈希表来记录已经遍…

六、长短时记忆网络语言模型(LSTM)

为了解决深度神经网络中的梯度消失问题&#xff0c;提出了一种特殊的RNN模型——长短期记忆网络&#xff08;Long Short-Term Memory networks, LSTM&#xff09;&#xff0c;能够有效的传递和表达长时间序列中的信息并且不会导致长时间前的有用信息被忽略。 长短时记忆网络原理…

vue iis 配置

下载安装两个IIS模块 1). 传送门&#xff1a;URL Rewrite 2). 传送门&#xff1a;Application Request Routing 注 : 只有在 服务器的主页 有Application Request Routing 部署VUE网站 生成网站 在VUE项目打包生成出发布文件,即文件夹 dist,此处忽略 复制到你需要存放网站的…

10 事务控制

文章目录 事务控制事务概述事务操作事务四大特性事务隔离级别 事务控制 事务概述 MySQL 事务主要用于处理操作量大&#xff0c;复杂度高的数据。比如说&#xff0c;在人员管理系统中&#xff0c;你删除一个人员&#xff0c;既需要删除人员的基本资料&#xff0c;也要删除和该…

kafka报文模拟工具的使用

日常项目中经常会碰到消费kafka某个topic的数据&#xff0c;如果知道报文格式&#xff0c;即可使用工具去模拟发送报文&#xff0c;以此测试代码中是否能正常消费到这个数据。 工具资源已上传&#xff0c;可直接访问连接下载&#xff1a;https://download.csdn.net/download/w…

Learn OpenGL 02 你好,三角形

图形渲染管线 图形渲染管线的每个阶段的抽象展示。要注意蓝色部分代表的是我们可以注入自定义的着色器的部分 首先&#xff0c;我们以数组的形式传递3个3D坐标作为图形渲染管线的输入&#xff0c;用来表示一个三角形&#xff0c;这个数组叫做顶点数据(Vertex Data)。 顶点着色…

编译内核错误 multiple definition of `yylloc‘

编译内核错误 # make ARCHarm CROSS_COMPILEarm-mix410-linux- uImageHOSTLD scripts/dtc/dtc /usr/bin/ld: scripts/dtc/dtc-parser.tab.o:(.bss0x10): multiple definition of yylloc; scripts/dtc/dtc-lexer.lex.o:(.bss0x0): first defined here collect2: error: ld ret…

昏暗场景增强-低照度增强-弱光增强(附代码)

引言 随着现代科技的发展&#xff0c;图像采集设备已经渗透到生活的方方面面&#xff0c;然而在昏暗场景、低照度或弱光条件下&#xff0c;图像的质量往往受到严重影响&#xff0c;表现为亮度不足、对比度低下、色彩失真以及细节丢失等问题。这类图像对于人眼识别和计算机视觉…

FPGA IBUFG

IBUFG和IBUFGDS的输入端仅仅与芯片的专用全局时钟输入管脚有物理连接&#xff0c;与普通IO和其它内部CLB等没有物理连接。 所以&#xff0c;IBUFG输入的不能直接接另外信号。 GTH transceiver primitives are called GTHE3_COMMON and GTHE3_CHANNEL in UltraScale FPGAs, an…

部署LVS+Keepalived高可用群集(抢占模式,非抢占模式,延迟模式)

目录 一、LVSKeepalived高可用群集 1、实验环境 2、 主和备keepalived的配置 2.1 yum安装ipvsadm和keepalived工具 2.2 添加ip_vs模块并开启ipvsadm 2.3 修改keepalived的配置文件 2.4 调整proc响应参数&#xff0c;关闭linux内核的重定向参数响应 2.5 将主服务器的kee…

SpringBoot整合Redis实现分布式锁

SpringBoot整合Redis实现分布式锁 分布式系统为什么要使用分布式锁&#xff1f; 首先&#xff0c;分布式系统是由多个独立节点组成的&#xff0c;这些节点可能运行在不同的物理或虚拟机器上&#xff0c;它们通过网络进行通信和协作。在这样的环境中&#xff0c;多个节点可能同…

群智能优化算法:巨型犰狳优化算法(GAO)求解23个基准函数(提供MATLAB代码)

一、巨型犰狳优化算法 巨型犰狳优化算法&#xff08;Giant Armadillo Optimization&#xff0c;GAO&#xff09;由Omar Alsayyed等人于2023年提出&#xff0c;该算法模仿了巨型犰狳在野外的自然行为。GAO设计的基本灵感来自巨型犰狳向猎物位置移动和挖掘白蚁丘的狩猎策略。GAO…

LLM 构建Data Muti-Agents 赋能数据分析平台的实践之①:数据采集

一、 概述 在推进产业数字化的过程中&#xff0c;数据作为最重要的资源是优化产业管控过程和提升产业数字化水平的基础一环&#xff0c;如何实现数据采集工作的便利化、高效化、智能化是降低数据分析体系运转成本以及推动数据价值挖掘体系的基础手段。随着数字化在产业端的推进…

电脑小问题:Windows更新后黑屏

Windows 更新后黑屏解决方法 在 Windows 更新后&#xff0c;伴随了一个小问题&#xff0c;电脑启动后出现了桌面黑屏。原因可能是火绒把 explorer.exe 当病毒处理了。 下面讲解 Windows 更新后黑屏的解决方法&#xff0c;步骤如下&#xff1a; 1. 按 ctrl alt delete 组合键…

JAVA实战开源项目:生活废品回收系统(Vue+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容三、界面展示3.1 登录注册3.2 资源类型&资源品类模块3.3 回收机构模块3.4 资源求购/出售/交易单模块3.5 客服咨询模块 四、免责说明 一、摘要 1.1 项目介绍 生活废品回收系统是可持续发展的解决方案&#xff0c;旨在鼓…

【操作系统概念】 第9章:虚拟内存管理

文章目录 0.前言9.1 背景9.2 按需调页9.2.1 基本概念9.2.2 按需调页的性能 9.3 写时复制9.4 页面置换9.4.1 基本页置换9.4.2 FIFO页置换9.4.3 最优(Optimal)置换9.4.4 LRU&#xff08;Least Recently Used&#xff09;页置换9.4.5 近似LRU页置换9.4.6 页缓冲算法 9.5 帧分配9.5…

遥遥领先!基于transformer变体的时间序列预测新SOTA!

目前&#xff0c;以CNN、RNN和 Transformer 模型为代表的深度学习算法已经超越了传统机器学习算法&#xff0c;成为了时间序列预测领域一个新的研究趋向。这其中&#xff0c;基于Transformer架构的模型在时间序列预测中取得了丰硕的成果。 Transformer模型因其强大的序列建模能…

JVM-垃圾收集器G1

G1垃圾回收器 概述&#xff1a; 是一款面向服务器的垃圾收集器,主要针对配备多个处理器及大容量内存的机器. 以极高效率满足GC停顿时间要求的同时,还具备高吞吐量性能特征.G1保留了年轻代和老年代的概念&#xff0c;但不再是物理隔阂了&#xff0c;它们都是&#xff08;可以不连…

Apache服务的搭建与配置

一、apache安装 systemctl stop firewalldsystemctl disable firewalldsetenforce 0yum -y install httpdsystemctl start httpdnetstat -ntlp | grep 80 二、认识主配置文件 # vim /etc/httpd/conf/httpd.conf ServerRoot "/etc/httpd" #定义工作目…