管理培训搜索
18318889481

IT
| 网络安全管理师

信息安全工程 网络蠕虫

| 系统集成项目管理工程师

每日一练 报名考试 考试大纲 知识考点 综合知识 直播动态 考试用书 政策法规 系统集成产学研实践 资质认定

| 金融科技师

职业前景 CGFT专题 政策动态

| 网络工程师

考试动态 每日一练 学习笔录 技术考点 知识考点 直播动态 考试用书 技术与应用 网络工程 网络技术入门 考试大纲

| 计算机学苑

数字媒体艺术 计算机科学与技术 软考报名 信息处理技术员 行业资讯 考试大纲 直播动态 网络安全 网络管理 通信技术 OpenHarmony 计算机与网络 企业信息化 软件工程 Linux 嵌入式Linux开发基础(ARMAtom) 离散数学 操作系统 C++程序设计 Java 语言程序设计 智能感知与无人系统 机器学习算法与人工智能 Python 软考资讯

| 计算机应用水平考试

考试动态 报考指南 全国计算机应用水平考试 中国计算机等级考试 江西计算机等级考试 广东计算机等级考试 江苏计算机等级考试 贵州计算机等级考试 湖南计算机等级考试 福建计算机等级考试 河南计算机等级考试 广西计算机等级考试 山西计算机等级考试 吉林计算机等级考试 江苏计算机等级考试 湖北计算机等级考试 北京计算机等级考试 安徽计算机等级考试 宁夏计算机等级考试 浙江计算机等级考试 陕西计算机等级考试 湖北计算机等级考试 河北计算机等级考试 天津计算机等级考试

| 电子商务平台

互联网营销师 电子商务师 农村电商

| 计算机技术与软件专业技术资格(水平)考试
| 信息系统项目管理师

学习笔记 考试动态 直播动态 考试用书 考试大纲 信息系统项目管理

| 信息系统监理师

IT实务 直播预告 信息系统监理师综合 答疑QA 监理资质

| 信息处理技术员

考试动态 直播动态 考试用书 知识分享 技术百科

| 【项目设计】自主HTTP服务器当前您所在的位置:首页 > IT > 网络工程师 > 技术与应用

文章目录

项目介绍

网络协议栈介绍

协议分层

数据的封装与分用

HTTP相关知识介绍

HTTP的特点

URL格式

URI、URL、URN

HTTP的协议格式

HTTP的请求方法

HTTP的状态码

HTTP常见的Header

CGI机制介绍

CGI机制的概念

CGI机制的实现步骤

CGI机制的意义

日志编写

套接字相关代码编写

HTTP服务器主体逻辑

HTTP请求结构设计

HTTP响应结构设计

EndPoint类编写

EndPoint结构设计

设计线程回调

读取HTTP请求

处理HTTP请求

构建HTTP响应

发送HTTP响应

差错处理

逻辑错误

读取错误

写入错误

接入线程池

设计任务

编写线程池

项目测试

首页请求测试

错误请求测试

GET方法上传数据测试

POST方法上传数据测试

项目扩展

项目源码

项目介绍

  本项目实现的是一个HTTP服务器,项目中将会通过基本的网络套接字读取客户端发来的HTTP请求并进行分析,最终构建HTTP响应并返回给客户端。

在这里插入图片描述

  HTTP在网络应用层中的地位是不可撼动的,无论是移动端还是PC端浏览器,HTTP无疑是打开互联网应用窗口的重要协议。


  该项目将会把HTTP中最核心的模块抽取出来,采用CS模型实现一个小型的HTTP服务器,目的在于理解HTTP协议的处理过程。


网络协议栈介绍

协议分层

协议分层

网络协议栈的分层情况如下:


在这里插入图片描述

网络协议栈中各层的功能如下:


应用层:根据特定的通信目的,对数据进行分析处理,以达到某种业务性的目的。

传输层:处理传输时遇到的问题,主要是保证数据传输的可靠性。

网络层:完成数据的转发,解决数据去哪里的问题。

链路层:负责数据真正的发生过程。

数据的封装与分用

数据的封装与分用

数据封装与分用的过程如下:

在这里插入图片描述


  也就是说,发送端在发生数据前,该数据需要先自顶向下贯穿网络协议栈完成数据的封装,在这个过程中,每一层协议都会为该数据添加上对应的报头信息。接收端在收到数据后,该数据需要先自底向上贯穿网络协议栈完成数据的解包和分用,在这个过程中,每一层协议都会将对应的报头信息提取出来。


  而本项目要做的就是,在接收到客户端发来的HTTP请求后,将HTTP的报头信息提取出来,然后对数据进行分析处理,最终将处理结果添加上HTTP报头再发送给客户端。

需要注意的是,该项目中我们所处的位置是应用层,因此我们读取的HTTP请求实际是从传输层读取上来的,而我们发送的HTTP响应实际也只是交给了传输层,数据真正的发送还得靠网络协议栈中的下三层来完成,这里直接说“接收到客户端的HTTP请求”以及“发送HTTP响应给客户端”,只是为了方便大家理解,此外,同层协议之间本身也是可以理解成是在直接通信的。


HTTP相关知识介绍

HTTP的特点

HTTP的五大特点

HTTP的五大特点如下:


客户端服务器模式(CS,BS): 在一条通信线路上必定有一端是客户端,另一端是服务器端,请求从客户端发出,服务器响应请求并返回。

简单快速: 客户端向服务器请求服务时,只需传送请求方法和请求资源路径,不需要发送额外过多的数据,并且由于HTTP协议结构较为简单,使得HTTP服务器的程序规模小,因此通信速度很快。

灵活: HTTP协议对数据对象没有要求,允许传输任意类型的数据对象,对于正在传输的数据类型,HTTP协议将通过报头中的Content-Type属性加以标记。

无连接: 每次连接都只会对一个请求进行处理,当服务器对客户端的请求处理完毕并收到客户端的应答后,就会直接断开连接。HTTP协议采用这种方式可以大大节省传输时间,提高传输效率。

无状态: HTTP协议自身不对请求和响应之间的通信状态进行保存,每个请求都是独立的,这是为了让HTTP能更快地处理大量事务,确保协议的可伸缩性而特意设计的。

说明一下:


随着HTTP的普及,文档中包含大量图片的情况多了起来,每次请求都要断开连接,无疑增加了通信量的开销,因此HTTP1.1支持了长连接Keey-Alive,就是任意一端只要没有明确提出断开连接,则保持连接状态。(当前项目实现的是1.0版本的HTTP服务器,因此不涉及长连接)

HTTP无状态的特点无疑可以减少服务器内存资源的消耗,但是问题也是显而易见的。比如某个网站需要登录后才能访问,由于无状态的特点,那么每次跳转页面的时候都需要重新登录。为了解决无状态的问题,于是引入了Cookie技术,通过在请求和响应报文中写入Cookie信息来控制客户端的状态,同时为了保护用户数据的安全,又引入了Session技术,因此现在主流的HTTP服务器都是通过Cookie+Session的方式来控制客户端的状态的。

URL格式

URL(Uniform Resource Lacator)叫做统一资源定位符,也就是我们通常所说的网址,是因特网的万维网服务程序上用于指定信息位置的表示方法。

一个URL大致由如下几部分构成:

在这里插入图片描述



简单说明:

http://表示的是协议名称,表示请求时需要使用的协议,通常使用的是HTTP协议或安全协议HTTPS。

user:pass表示的是登录认证信息,包括登录用户的用户名和密码。(可省略)

www.example.jp表示的是服务器地址,通常以域名的形式表示。

80表示的是服务器的端口号。(可省略)

/dir/index.html表示的是要访问的资源所在的路径(/表示的是web根目录)。

uid=1表示的是请求时通过URL传递的参数,这些参数以键值对的形式通过&符号分隔开。(可省略)

ch1表示的是片段标识符,是对资源的部分补充。(可省略)

注意:


如果访问服务器时没有指定要访问的资源路径,那么浏览器会自动帮我们添加/,但此时仍然没有指明要访问web根目录下的哪一个资源文件,这时默认访问的是目标服务的首页。

大部分URL中的端口号都是省略的,因为常见协议对应的端口号都是固定的,比如HTTP、HTTPS和SSH对应的端口号分别是80、443和22,在使用这些常见协议时不必指明协议对应的端口号,浏览器会自动帮我们进行填充。

URI、URL、URN

URI、URL、URN的定义

URI、URL、URN的定义如下:


URI(Uniform Resource Indentifier)统一资源标识符:用来唯一标识资源。

URL(Uniform Resource Locator)统一资源定位符:用来定位唯一的资源。

URN(Uniform Resource Name)统一资源名称:通过名字来标识资源,比如mailto:java-net@java.sun.com。

URI、URL、URN三者的关系

  URL是URI的一种,URL不仅能唯一标识资源,还定义了该如何访问或定位该资源,URN也是URI的一种,URN通过名字来标识资源,因此URL和URN都是URI的子集。


URI、URL、URN三者的关系如下:

在这里插入图片描述


绝对的URI和相对的URI

URI有绝对和相对之分:


绝对的URI: 对标识符出现的环境没有依赖,比如URL就是一种绝对的URI,同一个URL无论出现在什么地方都能唯一标识同一个资源。

相对的URI: 对标识符出现的环境有依赖,比如HTTP请求行中的请求资源路径就是一种相对的URI,这个资源路径出现在不同的主机上标识的就是不同的资源。

HTTP的协议格式

HTTP请求协议格式

HTTP请求协议格式如下:

在这里插入图片描述

HTTP请求由以下四部分组成:


请求行:[请求方法] + [URI] + [HTTP版本]。

请求报头:请求的属性,这些属性都是以key: value的形式按行陈列的。

空行:遇到空行表示请求报头结束。

请求正文:请求正文允许为空字符串,如果请求正文存在,则在请求报头中会有一个Content-Length属性来标识请求正文的长度。

HTTP响应协议格式

HTTP响应协议格式如下:

在这里插入图片描述

HTTP响应由以下四部分组成:

  • 状态行:[HTTP版本] + [状态码] + [状态码描述]。

  • 响应报头:响应的属性,这些属性都是以key: value的形式按行陈列的。

  • 空行:遇到空行表示响应报头结束。

  • 响应正文:响应正文允许为空字符串,如果响应正文存在,则在响应报头中会有一个Content-Length属性来标识响应正文的长度。

  • HTTP的请求方法

  • HTTP的请求方法

  • HTTP常见的请求方法如下:


  • GET方法和POST方法

  •   HTTP的请求方法中最常用的就是GET方法和POST方法,其中GET方法一般用于获取某种资源信息,而POST方法一般用于将数据上传给服务器,但实际GET方法也可以用来上传数据,比如百度搜索框中的数据就是使用GET方法提交的。


  •   GET方法和POST方法都可以带参,其中GET方法通过URL传参,POST方法通过请求正文传参。由于URL的长度是有限制的,因此GET方法携带的参数不能太长,而POST方法通过请求正文传参,一般参数长度没有限制。


  • HTTP的状态码

  • HTTP的状态码

  •   HTTP状态码是用来表示服务器HTTP响应状态的3位数字代码,通过状态码可以知道服务器端是否正确的处理了请求,以及请求处理错误的原因。


  • HTTP的状态码如下:

  • HTTP常见的Header

  • HTTP常见的Header

  • HTTP常见的Header如下:


  • Content-Type:数据类型(text/html等)。

  • Content-Length:正文的长度。

  • Host:客户端告知服务器,所请求的资源是在哪个主机的哪个端口上。

  • User-Agent:声明用户的操作系统和浏览器的版本信息。

  • Referer:当前页面是哪个页面跳转过来的。

  • Location:搭配3XX状态码使用,告诉客户端接下来要去哪里访问。

  • Cookie:用户在客户端存储少量信息,通常用于实现会话(session)的功能。

  • CGI机制介绍

  • CGI机制的概念

  • CGI(Common Gateway Interface,通用网关接口)是一种重要的互联网技术,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。CGI描述了服务器和请求处理程序之间传输数据的一种标准。

  • 实际我们在进行网络请求时,无非就两种情况:


  • 浏览器想从服务器上拿下来某种资源,比如打开网页、下载等。

  • 浏览器想将自己的数据上传至服务器,比如上传视频、登录、注册等。

  • 在这里插入图片描述

  •   通常从服务器上获取资源对应的请求方法就是GET方法,而将数据上传至服务器对应的请求方法就是POST方法,但实际GET方法有时也会用于上传数据,只不过POST方法是通过请求正文传参的,而GET方法是通过URL传参的。

  • 而用户将自己的数据上传至服务器并不仅仅是为了上传,用户上传数据的目的是为了让HTTP或相关程序对该数据进行处理,比如用户提交的是搜索关键字,那么服务器就需要在后端进行搜索,然后将搜索结果返回给浏览器,再由浏览器对HTML文件进行渲染刷新展示给用户。


  •   但实际对数据的处理与HTTP的关系并不大,而是取决于上层具体的业务场景的,因此HTTP不对这些数据做处理。但HTTP提供了CGI机制,上层可以在服务器中部署若干个CGI程序,这些CGI程序可以用任何程序设计语言编写,当HTTP获取到数据后会将其提交给对应CGI程序进行处理,然后再用CGI程序的处理结果构建HTTP响应返回给浏览器。

  • 在这里插入图片描述

  •   其中HTTP获取到数据后,如何调用目标CGI程序、如何传递数据给CGI程序、如何拿到CGI程序的处理结果,这些都属于CGI机制的通信细节,而本项目就是要实现一个HTTP服务器,因此CGI的所有交互细节都需要由我们来完成。

  • 何时需要使用CGI模式

  •   只要用户请求服务器时上传了数据,那么服务器就需要使用CGI模式对用户上传的数据进行处理,而如果用户只是单纯的想请求服务器上的某个资源文件则不需要使用CGI模式,此时直接将用户请求的资源文件返回给用户即可。


  •   此外,如果用户请求的是服务器上的一个可执行程序,说明用户想让服务器运行这个可执行程序,此时也需要使用CGI模式。


  • CGI机制的实现步骤

  • 一、创建子进程进行程序替换

  •   服务器获取到新连接后一般会创建一个新线程为其提供服务,而要执行CGI程序一定需要调用exec系列函数进行进程程序替换,但服务器创建的新线程与服务器进程使用的是同一个进程地址空间,如果直接让新线程调用exec系列函数进行进程程序替换,此时服务器进程的代码和数据就会直接被替换掉,相当于HTTP服务器在执行一次CGI程序后就直接退出了,这肯定是不合理的。因此新线程需要先调用fork函数创建子进程,然后让子进程调用exec系列函数进行进程程序替换。


  • 二、完成管道通信信道的建立

  •   调用CGI程序的目的是为了让其进行数据处理,因此我们需要通过某种方式将数据交给CGI程序,并且还要能够获取到CGI程序处理数据后的结果,也就是需要进行进程间通信。因为这里的服务器进程和CGI进程是父子进程,因此优先选择使用匿名管道。


  •   由于父进程不仅需要将数据交给子进程,还需要从子进程那里获取数据处理的结果,而管道是半双工通信的,为了实现双向通信于是需要借助两个匿名管道,因此在创建调用fork子进程之前需要先创建两个匿名管道,在创建子进程后还需要父子进程分别关闭两个管道对应的读写端。


  • 三、完成重定向相关的设置

  •   创建用于父子进程间通信的两个匿名管道时,父子进程都是各自用两个变量来记录管道对应读写端的文件描述符的,但是对于子进程来说,当子进程调用exec系列函数进行程序替换后,子进程的代码和数据就被替换成了目标CGI程序的代码和数据,这也就意味着被替换后的CGI程序无法得知管道对应的读写端,这样父子进程之间也就无法进行通信了。


  •   需要注意的是,进程程序替换只替换对应进程的代码和数据,而对于进程的进程控制块、页表、打开的文件等内核数据结构是不做任何替换的。因此子进程进行进程程序替换后,底层创建的两个匿名管道仍然存在,只不过被替换后的CGI程序不知道这两个管道对应的文件描述符罢了。


  •   这时我们可以做一个约定:被替换后的CGI程序,从标准输入读取数据等价于从管道读取数据,向标准输出写入数据等价于向管道写入数据。这样一来,所有的CGI程序都不需要得知管道对应的文件描述符了,当需要读取数据时直接从标准输入中进行读取,而数据处理的结果就直接写入标准输出就行了。


  •   当然,这个约定并不是你说有就有的,要实现这个约定需要在子进程被替换之前进行重定向,将0号文件描述符重定向到对应管道的读端,将1号文件描述符重定向到对应管道的写端。


  • 四、父子进程交付数据

  •   这时父子进程已经能够通过两个匿名管道进行通信了,接下来就应该讨论父进程如何将数据交给CGI程序,以及CGI程序如何将数据处理结果交给父进程了。


  • 父进程将数据交给CGI程序:


  • 如果请求方法为GET方法,那么用户是通过URL传递参数的,此时可以在子进程进行进程程序替换之前,通过putenv函数将参数导入环境变量,由于环境变量也不受进程程序替换的影响,因此被替换后的CGI程序就可以通过getenv函数来获取对应的参数。

  • 如果请求方法为POST方法,那么用户是通过请求正文传参的,此时父进程直接将请求正文中的数据写入管道传递给CGI程序即可,但是为了让CGI程序知道应该从管道读取多少个参数,父进程还需要通过putenv函数将请求正文的长度导入环境变量。

  • 说明一下: 请求正文长度、URL传递的参数以及请求方法都比较短,通过写入管道来传递会导致效率降低,因此选择通过导入环境变量的方式来传递。


  •   也就是说,使用CGI模式时如果请求方法为POST方法,那么CGI程序需要从管道读取父进程传递过来的数据,如果请求方法为GET方法,那么CGI程序需要从环境变量中获取父进程传递过来的数据。


  •   但被替换后的CGI程序实际并不知道本次HTTP请求所对应的请求方法,因此在子进程在进行进程程序替换之前,还需要通过putenv函数将本次HTTP请求所对应的请求方法也导入环境变量。因此CGI程序启动后,首先需要先通过环境变量得知本次HTTP请求所对应的请求方法,然后再根据请求方法对应从管道或环境变量中获取父进程传递过来的数据。


  •   CGI程序读取到父进程传递过来的数据后,就可以进行对应的数据处理了,最终将数据处理结果写入到管道中,此时父进程就可以从管道中读取CGI程序的处理结果了。


  • CGI机制的意义

  • CGI机制的处理流程

  • CGI机制的处理流程如下:

  • 在这里插入图片描述

  • 处理HTTP请求的步骤如下:


  • 判断请求方法是GET方法还是POST方法,如果是GET方法带参或POST方法则进行CGI处理,如果是GET方法不带参则进行非CGI处理。

  • 非CGI处理就是直接根据用户请求的资源构建HTTP响应返回给浏览器。

  • CGI处理就是通过创建子进程进行程序替换的方式来调用CGI程序,通过创建匿名管道、重定向、导入环境变量的方式来与CGI程序进行数据通信,最终根据CGI程序的处理结果构建HTTP响应返回给浏览器。

  • CGI机制的意义

  • CGI机制就是让服务器将获取到的数据交给对应的CGI程序进行处理,然后将CGI程序的处理结果返回给客户端,这显然让服务器逻辑和业务逻辑进行了解耦,让服务器和业务程序可以各司其职。

  • CGI机制使得浏览器输入的数据最终交给了CGI程序,而CGI程序输出的结果最终交给了浏览器。这也就意味着CGI程序的开发者,可以完全忽略中间服务器的处理逻辑,相当于CGI程序从标准输入就能读取到浏览器输入的内容,CGI程序写入标准输出的数据最终就能输出到浏览器。

  • 日志编写

  • 服务器在运作时会产生一些日志,这些日志会记录下服务器运行过程中产生的一些事件。


  • 日志格式

  • 本项目中的日志格式如下:

  • 在这里插入图片描述

  • 日志说明:

  • 日志级别: 分为四个等级,从低到高依次是INFO、WARNING、ERROR、FATAL。

  • 时间戳: 事件产生的时间。

  • 日志信息: 事件产生的日志信息。

  • 错误文件名称: 事件在哪一个文件产生。

  • 行数: 事件在对应文件的哪一行产生。

  • 日志级别说明:


  • INFO: 表示正常的日志输出,一切按预期运行。

  • WARNING: 表示警告,该事件不影响服务器运行,但存在风险。

  • ERROR: 表示发生了某种错误,但该事件不影响服务器继续运行。

  • FATAL: 表示发生了致命的错误,该事件将导致服务器停止运行。


我们可以将套接字相关的代码封装到TcpServer类中,在初始化TcpServer对象时完成套接字的创建、绑定和监听动作,并向外提供一个Sock接口用于获取监听套接字。


此外,可以将TcpServer设置成单例模式:


将TcpServer类的构造函数设置为私有,并将拷贝构造和拷贝赋值函数设置为私有或删除,防止外部创建或拷贝对象。

提供一个指向单例对象的static指针,并在类外将其初始化为nullptr。

提供一个全局访问点获取单例对象,在单例对象第一次被获取的时候就创建这个单例对象并进行初始化。

课程
财会类
税务类
金融类
经管类
认证类
学历类
建工类
健康类
专家
政府专家
财税名家
高校教授
文化传媒
金融科技
金融电子化
企业管理
财政金融
生物医药
诺贝尔奖得主
合规法律
科学技术
银行智库
财会
中国注册会计师
AIA
会计实务
会计实操
财务经理人
初级会计师
税务实务
中级会计师
中国会计智库
CFO成长营
会计学苑
建工
二级造价工程师
建筑工程资讯
二级建造师
一级造价工程师
监理工程师
消防设施操作员
产教融合
建工学苑
一级建造师
安全工程师
消防工程师
造价工程事务所
BIM工程师
经管
转创人力
中级经济师
二级人力资源管理师
三级人力资源师
人力资源管理师
碳排放管理师
期刊中心
教材参考
军队文职人员
产教融合
劳动关系协调员
初、中级经济考试
企业合规师
初级经济师
企业人力资源管理师
职业指导师
教育
专升本
成人高等教育
自考中国
自学考试研究所
普通专升本
小自考中心
高等继续教育学院
教师资格中心
智库与社会服务
高等职业本科
金融
证券从业
基金从业
金融智库
银行从业
转创博学
ICCM
项目
高管培训
国际学历
财经证书
专项课程
企业内训
教育技术产品
高校学科建设服务
教学资源开发
国际合作服务
产业服务
国内院校
海外院校
海外留学
合作院校
观点
政治经济
IT&财务融合
高校教授
文化传媒
金融科技
金融电子化
企业管理
财政金融
生物医药
诺贝尔奖
合规法律
科学技术
银行智库
商业产经
医卫
医卫健康
主管药师
保育员
药卫学苑
心理咨询师
家庭照护员
养老护理员
健康管理师
公共营养师
执业药师
育婴师(员)
主管护师
护士执业
医院招聘
IT
网络安全管理师
系统集成项目管理工程师
金融科技师
网络工程师
计算机学苑
计算机应用水平考试
电子商务平台
计算机技术与软件专业技术资格(水平)考试
信息系统项目管理师
信息系统监理师
信息处理技术员
考研
考研资讯
信息中心
专业硕士
考研公共课
同等学力申硕中心
复试调剂
研究生工作
考研中国
硕士入学考试
考研直播动态
社工
社会工作者
技能中国
智库与社会服务
初级社会工作者
中级社会工作者
报考动态
社会工作事务所
职称评审
家庭教育指导师
转创网校APP
18318889481
在线QQ
在线留言
返回首页
返回顶部
留言板
发送