一步步开发一个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

相关文章

服务器集群同步时间手记

1.时间服务器配置(必须root用户) (1)检查ntp是否安装 [root@node1 桌面]# rpm -qa|grep ntpntp-4.2.6p5-10.el6.centos.x86_64fontpackages-filesystem-1.41-1.1.el6.noarchntpdate-4.2.6p5-10.el6.centos.x86_64 (2)修改ntp配置文件 [r

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

Java Web指的是什么

Java Web指的是使用Java技术进行Web开发的一种方式。Java在Web开发领域有着广泛的应用,主要通过Java EE(Enterprise Edition)平台来实现。  主要特点和技术包括: 1. Servlets和JSP:     Servlets 是Java编写的服务器端程序,用于处理客户端请求和生成动态网页内容。     JSP(JavaServer Pages)

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

BUUCTF靶场[web][极客大挑战 2019]Http、[HCTF 2018]admin

目录   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 [web][HCTF 2018]admin 考点:弱密码字典爆破 四种方法:   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 访问环境 老规矩,我们先查看源代码

【区块链 + 人才服务】区块链集成开发平台 | FISCO BCOS应用案例

随着区块链技术的快速发展,越来越多的企业开始将其应用于实际业务中。然而,区块链技术的专业性使得其集成开发成为一项挑战。针对此,广东中创智慧科技有限公司基于国产开源联盟链 FISCO BCOS 推出了区块链集成开发平台。该平台基于区块链技术,提供一套全面的区块链开发工具和开发环境,支持开发者快速开发和部署区块链应用。此外,该平台还可以提供一套全面的区块链开发教程和文档,帮助开发者快速上手区块链开发。