我们先了解一下这个项目最终能达到的一个目标,然后以这个来进行项目的分析:
1、实现最基本的HTTP/1.0版本的web服务器,客户端能够使用GET、POST方法请求资源
2、服务器将客户请求的资源以html页面的形似呈现,并能够进行差错处理(如:客户请求的资源不存在时,服务器能够返回一个404的页面)
3、服务器能进行简单的cgi运行。比如当客户在表单中输入数据后,服务器能够将运行结果返回个客户
4、能够通过页面对数据库进行操作,如增删查改等操作

一、http服务器实现的基本框架

  • 关于HTTP协议
    即超文本传输协议,是互联网上应用最广泛的网络协议。它是应用层的协议,底层是基于TCP通信的。HTTP协议的工作过程:客户通过浏览器向服务器发送文档请求,浏览器将请求的资源回应给浏览器,然后关闭连接。即:连接->请求->响应->关闭连接。
  • 关于URL
    即统一资源定位符,每个网页都对应一个URL地址(俗称网址),具有全球唯一性。它包含的信息指出文件的位置以及浏览器应该怎么处理它。 一个完整的URL包括协议类型、主机类型、路径和文件名。
    http协议的URL格式: http: //host[:port][abs_path] ,http表示使用http协议来进行资源定位;host是主机域名;port是端口号,一般有默认的;abs_path代表资源的路径。
    这里我主要介绍项目中涉及的URL的两种格式—URL带参数和不带参数的。

    GET方法使用的是带参数的URL,即传递的参数会使用?连接在资源路径后边;POST方法使用的是不带参数的URL,它的参数是通过http请求报头中的请求消息体传递给服务器的。
  • 关于HTTP的请求与响应格式

    响应报头中的状态码和状态码描述,例如:当请求的资源不存在时,会收到“404 NotFound”的页面,404就是状态码,“NotFound”就是状态码描述,即请求的文件不存在。

二、服务器实现的基本思路

1、http协议是基于TCP通信的协议,因此,实现web服务器的第一步至少要能实现两个主机不同进程之间的TCP通信。
2、接下来的部分就是比较主要的处理逻辑了,当服务器收到请求后,首先应该分析请求方法(因为web服务器是要支持cgi的,但请求方法不同处理cgi也不同,这里我们只处理GET和POST方法)。
3、当方法确定后,应该拿到请求的URL,这一步是为了我们后边能处理GET和POST方法的cgi(GET和POST的参数位置不同,GET的参数在URL中,POST的参数在请求正文中)
4、判断资源是否存在,如果存在,判断这个资源是一个目录、普通文件还是一个可执行程序。之前几步我们已经提取到URL以及参数。GET方法:如果没有参数,就直接将请求的资源返回(即进入非cgi模式运行);否则,进入cgi模式内部运行;只要是POST方法就需要支持cgi:直接进入cgi函数内部运行。

非cgi模式:
进入非cgi模式时一定是GET方法且没有参数,此时进入echo_www()函数内部即可,该函数会将所请求的资源以html的格式返回给浏览器。

cgi模式:

上述这张图描述了运行cgi时的过程,首先服务器要从浏览器上读取参数,然后需要fork出一个子进程进行cgi部分的处理,父进程通过环境变量的方式将参数转交给子进程,子进程运行完成后,将结果交给父进程,父进程再将数据输出给浏览器。在这个过程中可以将父进程看作一个所谓的中间量,只进行了参数的转交,因此可以将子进程的输入输出文件描述符进行重定向,即子进程直接与浏览器“联系”。

下面总结出父子进程内部各自需要干的事情:

三、错误处理

错误处理这部分的实现可以参考echo_www()函数,但需要改变响应的消息报头的格式,即改变状态码,状态码描述,以及返回的页面。例如当请求的资源不存在时,服务器需要返回给浏览器一个默认的404页面,告诉客户请求的资源不存在。效果如图:

四、项目文件


目录:
cgi:运行cgi部分的实现代码
conf:配置文件,存放需要绑定的服务器的ip和port
log:shell的日志文件以及http错误处理的日志文件
lib:mysql需要的lib库
sql_client:mysql部分的API及CGI实现
wwwroot:web服务器工作的根目录,包含各种资源页面(例如默认的index.html页面,差错处理的404页面),以及执行cgi的可执行程序

文件:
configure.sh:sheel脚本,运行该shell脚本后需要自动生成Makefile文件
http_ctl.sh:服务器控制脚本,需要实现服务器的启动、暂停以及重新启动
httpd.pid:与http_ctl.sh配合使用。如果把服务器变成守护进程在后台运行,重新启动时就需要检测服务器是否启动,该文件存放服务器启动以后的进程id
httpd.h:服务器的方法声明
httpd.c:方法实现
main.c:服务器的主逻辑

五、实现结果

请求资源存在:

运行cgi后:

六、源码:

https://github.com/lybb/Linux/tree/master/httpd

附:
这里是我遇到的一些问题,粘出来,也可能是你遇到的问题:
1、本地环回测试ok,Linux下的浏览器测试也可以,但不能接外部的浏览器访问(没有设置桥接模式)嗯~要是在外部浏览器测试的话千万别忘记关闭防火墙
2、服务器应答时,没有将html格式的页面发送,而是将底层的实现代码展示在浏览器,并且在调试时将本来要打印的调试信息会打印到网页上(在回应空行时将send期望发送的数值写的太大,本来只需要发送两个字节的内容)
解决:先检查代码,思路正确,在容易出现问题的地方加入调试信息,最后将问题定位在echo_www()函数内
3、不能显示图片(这个问题是没有将所有发送的情况考虑完全,只考虑到目录、可执行程序,但没有考虑到如果请求的是一个路径明确的普通文件)
解决:测试请求一个路径明确的test.html文件,加入调试信息 ,将问题定位在:如果请求的资源存在,应该如何处理。对于普通文件,找到后并回显给浏览器;如果是目录,应答的是默认页面;如果是可执行程序,执行后返回结果
4、能显示图片后,但显示的不完整(原因:echo_www中,期望读取一行信息的line值太小,不能存下一张图片)
5、运行cgi模式时,每次提交数据并进行submit后都会自动出现提醒下载的页面
原因:在响应报头中,将Content-Type中的”text”写成”test”。而浏览器对于不能识别或解析的实体,都会提醒用户下载。

基于HTTP协议实现的小型web服务器相关推荐

  1. mysql 花生壳 2003_基于HTTP协议实现的小型web服务器的方法

    这篇文章主要介绍了基于HTTP协议实现的小型web服务器的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 我们先了解一下这个 ...

  2. 项目--基于http协议的小型web服务器

    在我们对网络的学习过程中,会接触到网络编程,我们在网络中可以深刻认识到服务器与客户端的交互,当我们输入网址时背后发生的一系列后端操作,为了加深我们对网络部分的学习,我们找到了一个开源项目TinyWeb ...

  3. 基于HTTP实现的小型web服务器

    主要流程为:服务器获得请求–>响应并处理请求–>返回结果. 完整的HTTP过渡到TCP实现客户端与服务器的交互过程 1.当客户端执行网络请求的时候,从url中解析出url的主机名,并将主机 ...

  4. 自主开发的小型Web服务器

    自主开发的小型Web服务器 1. 技术特点 2. 具体步骤 3. CGI技术 4. Mysql连接 5. Gitee原码链接 6. 参考Blog 1. 技术特点 网络编程(http协议,TCP/IP协 ...

  5. 自主小型Web服务器实现——TinyHttp

    目录 一.功能 二.技术特点 三.主要框架 四.CGI技术 五.流程 六.具体实现细节 6.1 套接字部分 6.2 线程池部分 6.3 协议处理部分(主要部分) 七.测试结果 一.功能 实现一个自主开 ...

  6. linux线程池实现多线程并发,基于Linux的多线程池并发Web服务器设计-电子设计工程.PDF...

    基于Linux的多线程池并发Web服务器设计-电子设计工程.PDF 第 卷 第 期 电子设计工程 年 月 基于 的多线程池并发 服务器设计 陈 涛 任海兰 武汉邮电科学研究院 湖北 武汉 摘要 时至今 ...

  7. 基于Boost::beast模块的小型http服务器

    基于Boost::beast模块的小型http服务器 实现功能 C++实现代码 实现功能 基于Boost::beast模块的小型http服务器 C++实现代码 #include <boost/b ...

  8. 基于安卓手机使用Termux搭建web服务器教程

    基于安卓手机使用Termux搭建web服务器教程 一.软件的准备 Termux Android5.0以上的手机(最好root) Xshell 6(windows软件) 二.前期Termux的设置与安装 ...

  9. 网络云存储技术Windows server 2012 (项目二十 一 基于Cluster的高可用企业WEB服务器的部署)

    网络云存储技术Windows server 2012 (项目二十一 基于Cluster的高可用企业WEB服务器的部署) 前言 网络存储技术,是以互联网为载体实现数据的传输与存储,它采用面向网络的存储体 ...

最新文章

  1. 手把手教你定制标准 Spring Boot starter
  2. linux里hba状态_在Linux/Unix平台查看HBA卡的WWN号 和状态
  3. SAP中PDF文件本地保存方法
  4. 朴素贝叶斯(Naive Bayes),“Naive”在何处?
  5. Openssl搭建私有CA认证
  6. floodlight ovs 更改拓扑_淘宝更改类目降权多久?被降权了怎么办?_推广运营(淘宝天猫)...
  7. 开挂的印度裔00后:7岁“出道”教编程,12岁成为IBM荣誉顾问
  8. max无法创建新的堆栈防护页面_交互设计师,新媒体艺术家们请注意:2019MaxMSP必读书单来袭!...
  9. servlet技术是否过时
  10. 存储类、链接、内存管理
  11. [Ext JS6]Ext.Template
  12. spark.network.timeout参数入门
  13. 手游联运系统包括什么功能?
  14. 阿里CEO张勇:打破各企业边界 联手对抗黑灰产
  15. 从网易博客转入CSDN
  16. LSVGlobal Mapper应用----影像裁剪
  17. 少儿编程微课程7:星际飞行单机版
  18. 【ELT.ZIP】OpenHarmony啃论文俱乐部—一种深度神经网压缩算法
  19. java如何进行word文档的合并
  20. 51单片机学习:LED闪烁实验

热门文章

  1. lenovo微型计算机c320拆机,lenovo c4030一体机怎么拆机添加内存条?
  2. 15Microsoft SQL Server 数据库维护
  3. 目标检测中评估每类目标在IOU为0.5的PrecisionRecall
  4. 计算机二级msoffice知识点汇总,计算机二级MS office知识点
  5. 处理登录问题遇到的后台数据未定义问题
  6. 推荐!《未来战场形态》(译文),美国国家情报委员会
  7. 谈网络攻击:克里姆林宫暗讽美“泼脏水”
  8. 铁路信号设备防雷,铁路行业防雷接地工程解决方案
  9. 有关Lucene的问题(2):stemming和lemmatization
  10. Elasticsearch 与mysql数据同步