基于HTTP协议实现的小型web服务器的方法

我们先了解一下这个项目最终能达到的一个目标,然后以这个来进行项目的分析:
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服务器的方法的文章就介绍到这了,更多相关HTTP小型web服务器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • VPS CentOS-6 下 LNMP HTTP web服务器的搭建步骤

    笔者于昨天新入手了一个 VPS, 来作为个人博客wid实验室(widlabs.com)开发的实验环境.所以在这篇博文中, 将介绍 CentOS 6 下 LNMP HTTP 环境的搭建, 从使用 ssh 登录VPS讲起, 一直到将域名解析到服务器IP上这一完整的网站搭建流程. 新入手的VPS基本配置如下: 虚拟化技术: OpenVZ操作系统: CentOS-6 x86_64 BaseCPU: Intel(R) Xeon(R) CPU E3-1240 V2 @ 3.40GHz内存: 2GB硬盘: 5

  • HTTP与HTTP协作的Web服务器访问流程图解

    一台web服务器可搭建多个独立域名的web网站,也可作为通信路径上的中转服务器提升传输效率. 一.用单台虚拟主机实现多个域名 HTTP/1.1规范允许一台HTTP服务器搭建多个web站点. 即使物理层面只有一台服务器,但只要使用虚拟主机的功能,则可以假想已具有多台服务器. 在互联网上,域名通过DNS服务映射到IP地址(域名解析)之后访问目标网站.可见,当请求发送到服务器时,已经是以IP地址形式访问了. 所以,如果一台服务器内托管了www.tricorder.jp和www.hackr.jp这两个域

  • 基于HTTP协议实现的小型web服务器的方法

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

  • Android基于Http协议实现文件上传功能的方法

    本文实例讲述了Android基于Http协议实现文件上传功能的方法.分享给大家供大家参考,具体如下: 注意一般使用Http协议上传的文件都比较小,一般是小于2M 这里示例是上传一个小的MP3文件 1.主Activity:MainActivity.java public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private EditText timel

  • 利用node.js搭建简单web服务器的方法教程

    前言 使用Nodejs搭建Web服务器是学习Node.js比较全面的入门教程,因为要完成一个简单的Web服务器,你需要学习Nodejs中几个比较重要的模块,比如:http协议模块.文件系统.url解析模块.路径解析模块.以及301重定向问题,下面我们就简单讲一下如何来搭建一个简单的Web服务器. 早先不使用web服务器的情况下想要在浏览器端访问本地资源,可以利用firefox浏览器,其可以自己启动一个小型web服务器. 为了让刚接触node的人也能大体看懂,本文的代码我将尽量简化. 准备 首先,

  • Go语言实现简单Web服务器的方法

    本文实例讲述了Go语言实现简单Web服务器的方法.分享给大家供大家参考.具体分析如下: 包 http 通过任何实现了 http.Handler 的值来响应 HTTP 请求: package http type Handler interface { ServeHTTP(w ResponseWriter, r *Request) } 在这个例子中,类型 Hello 实现了 http.Handler. 注意: 这个例子无法在基于 web 的指南用户界面运行.为了尝试编写 web 服务器,可能需要安装

  • 在Android设备上搭建Web服务器的方法

    一般而言,Android 应用在请求数据时都是以 Get 或 Post 等方式向远程服务器发起请求,那你有没有想过其实我们也可以在 Android 设备上搭建一个小型 Web 服务器,并且实现常规的下载图片.下载文件.提交表单等功能呢? 下面要介绍的就是如何在 Android 设备上搭建一个 Web 服务器,这个 Web 服务器的功能有如下几点: 接受客户端文件上传.下载文件 动态 Http API,像 Java 的 Servlet 一样写接口 部署静态网站,例如纯Html,支持 JS.CSS.

  • php使用socket post数据到其它web服务器的方法

    本文实例讲述了php使用socket post数据到其它web服务器的方法.分享给大家供大家参考.具体实现方法如下: function post_request($url, $data, $referer='') { // Convert the data array into URL Parameters like a=b&foo=bar etc. $data = http_build_query($data); // parse the given URL $url = parse_url(

  • Go语言使用HTTP包创建WEB服务器的方法

    本文实例讲述了Go语言使用HTTP包创建WEB服务器的方法.分享给大家供大家参考,具体如下: 在Golang中写一个http web服务器大致是有两种方法: 1 使用net包的net.Listen来对端口进行监听 2 使用net/http包 这里是讨论如何使用net/http包创建一个web服务器 net/http请求提供了HTTP客户端和服务端的具体实现 http客户端 先看到的是Get,Post,PostForm三个函数.这三个函数直接实现了http客户端 复制代码 代码如下: import

  • java使用socket实现一个多线程web服务器的方法

    除了服务器类,还包括请求类和响应类 请求类:获取客户的HTTP请求,分析客户所需要的文件 响应类:获得用户请求后将用户需要的文件读出,添加上HTTP应答头.发送给客户端. 服务器处理类 package com.lp.app.webserver; import java.io.*; import java.net.*; //使用Socket创建一个WEB服务器,本程序是多线程系统以提高反应速度. class WebServer { public static String WEBROOT = "&

  • python静态web服务器实现方法及代码详解

    1.编写TCP服务器程序. 2.获取浏览器发送的http请求消息数据. 3.读取固定的页面数据,将页面数据组装成HTTP响应消息数据并发送给浏览器. 4.HTTP响应报文数据发送完成后,关闭服务于客户端的套接字. 实例 # 时间: 2021/10/21 20:38 import socket if __name__ == '__main__': # 创建tcp服务端套接字 tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_

  • 如何将 Nginx 配置为Web服务器的方法

    阅读之前,建议先阅读初识 Nginx. 之后,我们来了解一下 Nginx 配置. 抽象来说,将 Nginx 配置为 Web 服务器就是定义处理哪些 URLS 和如何处理这些URLS 对应的请求.具体来说,就是定义一些虚拟服务器(Virtual Servers),控制具有特定 IP 和域名的请求. 更具体的来说, Nginx 通过定义一系列 locations 来控制对 URIS 的选择.每一个 location 定义了对映射到自己的请求的处理场景:返回一个文件或者代理请求,或者根据不同的错误代码

随机推荐