一步步开发一个Web服务器.Part 1.

2024-08-28 13:32

本文主要是介绍一步步开发一个Web服务器.Part 1.,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文链接:Let’s Build A Web Server. Part 1.
译文链接:ZKeeer’s Blog
原文代码基于python2,本文代码基于python3

本系列其他文章:
【翻译】一步步开发一个Web服务器.Part 1.
【翻译】一步步开发一个Web服务器.Part 2.
【翻译】一步步开发一个Web服务器.Part 3.

一个女人外出散步,路过一个工地,看到三个人在工作。她问第一个人,“你在做什么呀?” 第一个人不耐烦地冲她吼:“你没看到我在垒砖啊?!” 她不满足于这个回答,又问了第二个人他在做什么。第二个人回答道:“我在砌一堵墙。” 第二个人转向第一个人,说道:“嘿!你砌过头了,赶紧把最后一块儿转拿掉。” 女人还是对这个答案不满意,她问了第三个人同样的问题。第三个人仰望天空,说:“我在盖一座迄今为止世界上最大的教堂。” 他站在这儿仰望着天空,背后那两个人却还在为那块儿不合时宜地砖争论不休。他对第一个人说,“哥们,不用担心那块砖了,那是内墙,最后会涂满涂料,不会有人看见那块儿砖。开始垒另一层好了。”

这个故事地寓意是当你了解了整个系统并且明白不同部分(砖,墙,教堂)是如何组合在一起的时候,你才能更快地明确并解决问题(摆放不对的砖)。

该如何从头创建你的Web服务器呢?

我相信成为一个更好地开发人员,你必须更好地明白你日常使用的底层软件系统,这底层软件系统包括编程语言、编译器和解释器、数据库和操作系统、web服务器和web框架。并且,为了更好的,更深入的理解这些系统,你必须一砖一瓦地从头重建一遍。

正如孔子所说:不闻不若闻之,闻之不若见之,见之不若知之,知之不若行之。(实际出于《荀子·儒效》,是荀子说的)

这里写图片描述
这里写图片描述
这里写图片描述

在这点儿上,我希望你能坚信,从头重建不同软件系统以了解它们如何运行是一个极好的方法。

在这系列地三部分文章中,我将带领你怎样写出你自己地web服务器。来,开始吧!

第一件事,什么是web服务器呢?
这里写图片描述

简言之,它是个部署在物理服务器上地网络服务器(oops,object-oriented programming system,a server on server),并且等着客户端向它发送请求。当它接收到一个请求,它会产生一个响应并且发送回去。客户端和服务器之间的交流基于HTTP协议。这个客户端可以是你的浏览器或者其他任何使用HTTP协议的软件。

一个最简单的web服务器实现应该是怎样的?这是我的看法。这个例子基于python(这是一门非常简单易学的语言,人生苦短,快用python),即使你不知道python是什么鬼,也不耽误你理解下面的代码和概念。

import socketHOST, PORT = '', 8888listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listen_socket.bind((HOST, PORT))
listen_socket.listen(1)
print('Serving HTTP on port %s ...' % PORT)
while True:client_connection, client_address = listen_socket.accept()request = client_connection.recv(1024)print(request)http_response = b"""\HTTP/1.1 200 OKHello, World!"""client_connection.sendall(http_response)client_connection.close()

译者注:http_response必须为bytes类型,通过加b解决。

保存上面的代码,命名为webserver1.py或者从我的github上down下来,用下面的命令运行:

$ python webserver1.py
Serving HTTP on port 8888

运行之后,在你的浏览器中输入 http://localhost:8888/hello 敲回车,然后你会惊讶“还有这种操作?!”你的浏览器中会出现如下:
这里写图片描述

撸起袖子加油干!等你凯旋归来!

…接下来我们讨论一下它实际工作原理。

首先,我们从上面输入的地址入手。此地址叫做URL(统一资源定位器),来看看它的结构:
这里写图片描述
这就是你告诉你的浏览器要找到的web服务器,链接到那个服务器上的页面并且给你取回来。在你的浏览器发送一个HTTP请求之前,它会和服务器建立一个TCP连接。然后通过TCP链接给服务器发送一个HTTP请求,等着web服务器返回一个响应。当你的浏览器接收到这个请求后,会在浏览器中展示出来,在这个例子中浏览器显示的是“Hello World!”

在发送HTTP请求并得到回应之前,客户端和服务器是怎样建立一个TCP链接的,接下来细细探究。为了建立TCP链接,服务器和客户端都使用了所谓的sockets。接下来我们使用telnet命令行模拟浏览器而不是直接用浏览器。

在同一台电脑上,运行web服务器,同时在命令行启动telnet会话。指定一个连接的主机和端口,例如localhost 8888

$ telnet localhost 8888
Trying 127.0.0.1Connected to localhost.

此时,你已经和本机上的web服务器及那里了一个TCP连接,可以准备发送接收消息了。在下图中,你可以看到服务器在接受一个新的TCP连接之前所进行的标准流程。
这里写图片描述
在上面打开的telnet会话中,输入

GET/hello HTTP/1.1

回车。

$ telnet localhost 8888
Trying 127.0.0.1 …
Connected to localhost.
GET /hello HTTP/1.1HTTP/1.1 200 OK
Hello, World!

恭喜!你模拟了一个浏览器。与此同时,你发送了一个HTTP请求并得到了一个HTTP响应。HTTP请求的基本结构如下:
这里写图片描述
HTTP请求包含了HTTP方法(这里使用的是GET方法,因为我们要服务器返回给我们响应)、表示服务器上页面的路径例如 /hello、协议版本。

为简单起见,此时我们的Web服务器完全忽略了上述请求。你可以输入任何无意义的输入,你得到的还会是“Hello World!”的响应。

一旦我们输入了请求点击回车,客户端会发送这个请求给服务器,服务器会读取请求,打印出来并且返回响应的HTTP响应。

下图是服务器发送给客户端的HTTP响应:
这里写图片描述
我们来解析一下这个响应。响应包含了HTTP版本、HTTP状态,紧跟着一个必须的空行,然后是响应的主体。

这个响应状态 HTTP/1.1 200 OK 包含了HTTP版本、HTTP状态码、HTTP状态码对应的原因短语OK 。当浏览器接收到这个响应时,它展示了响应的主体部分,这就是为什么你能在浏览器看到“Hello World!”

那是一个最基本的web服务器模型。总结一下:web服务器创建了一个监听套接字,并且开启了一个循环,不断接受新的连接。客户端初始化一个TCP连接,成功建立连接之后,客户端发送给服务器HTTP请求,得到一个服务器的HTTP响应,解析这个响应展示给用户。为了建立这个TCP连接,客户端和服务器都使用了sockets。

现在我们已经建立了一个最基础的web服务器,你可以用你的浏览器或者其他HTTP客户端进行测试。正如上文所示,你可以用telnet通过输入请求来模拟一个HTTP客户端。

留一个课后作业题:不改变服务器代码的情况下,怎样在你刚完成的服务器上运行一个Django、Flask、Pyramid应用,适应不同的web框架?

我会在Part 2中讲解,敬请期待。

这篇关于一步步开发一个Web服务器.Part 1.的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1114899

相关文章

JSON Web Token在登陆中的使用过程

《JSONWebToken在登陆中的使用过程》:本文主要介绍JSONWebToken在登陆中的使用过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录JWT 介绍微服务架构中的 JWT 使用结合微服务网关的 JWT 验证1. 用户登录,生成 JWT2. 自定义过滤

一文教你如何将maven项目转成web项目

《一文教你如何将maven项目转成web项目》在软件开发过程中,有时我们需要将一个普通的Maven项目转换为Web项目,以便能够部署到Web容器中运行,本文将详细介绍如何通过简单的步骤完成这一转换过程... 目录准备工作步骤一:修改​​pom.XML​​1.1 添加​​packaging​​标签1.2 添加

利用Python开发Markdown表格结构转换为Excel工具

《利用Python开发Markdown表格结构转换为Excel工具》在数据管理和文档编写过程中,我们经常使用Markdown来记录表格数据,但它没有Excel使用方便,所以本文将使用Python编写一... 目录1.完整代码2. 项目概述3. 代码解析3.1 依赖库3.2 GUI 设计3.3 解析 Mark

CentOS 7部署主域名服务器 DNS的方法

《CentOS7部署主域名服务器DNS的方法》文章详细介绍了在CentOS7上部署主域名服务器DNS的步骤,包括安装BIND服务、配置DNS服务、添加域名区域、创建区域文件、配置反向解析、检查配置... 目录1. 安装 BIND 服务和工具2.  配置 BIND 服务3 . 添加你的域名区域配置4.创建区域

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

Windows Server服务器上配置FileZilla后,FTP连接不上?

《WindowsServer服务器上配置FileZilla后,FTP连接不上?》WindowsServer服务器上配置FileZilla后,FTP连接错误和操作超时的问题,应该如何解决?首先,通过... 目录在Windohttp://www.chinasem.cnws防火墙开启的情况下,遇到的错误如下:无法与

基于Python开发批量提取Excel图片的小工具

《基于Python开发批量提取Excel图片的小工具》这篇文章主要为大家详细介绍了如何使用Python中的openpyxl库开发一个小工具,可以实现批量提取Excel图片,有需要的小伙伴可以参考一下... 目前有一个需求,就是批量读取当前目录下所有文件夹里的Excel文件,去获取出Excel文件中的图片,并

基于Python开发PDF转PNG的可视化工具

《基于Python开发PDF转PNG的可视化工具》在数字文档处理领域,PDF到图像格式的转换是常见需求,本文介绍如何利用Python的PyMuPDF库和Tkinter框架开发一个带图形界面的PDF转P... 目录一、引言二、功能特性三、技术架构1. 技术栈组成2. 系统架构javascript设计3.效果图

Windows server服务器使用blat命令行发送邮件

《Windowsserver服务器使用blat命令行发送邮件》在linux平台的命令行下可以使用mail命令来发送邮件,windows平台没有内置的命令,但可以使用开源的blat,其官方主页为ht... 目录下载blatBAT命令行示例备注总结在linux平台的命令行下可以使用mail命令来发送邮件,Win

基于Python开发PDF转Doc格式小程序

《基于Python开发PDF转Doc格式小程序》这篇文章主要为大家详细介绍了如何基于Python开发PDF转Doc格式小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用python实现PDF转Doc格式小程序以下是一个使用Python实现PDF转DOC格式的GUI程序,采用T