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

相关文章

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

Linux云服务器手动配置DNS的方法步骤

《Linux云服务器手动配置DNS的方法步骤》在Linux云服务器上手动配置DNS(域名系统)是确保服务器能够正常解析域名的重要步骤,以下是详细的配置方法,包括系统文件的修改和常见问题的解决方案,需要... 目录1. 为什么需要手动配置 DNS?2. 手动配置 DNS 的方法方法 1:修改 /etc/res

基于Python开发Windows自动更新控制工具

《基于Python开发Windows自动更新控制工具》在当今数字化时代,操作系统更新已成为计算机维护的重要组成部分,本文介绍一款基于Python和PyQt5的Windows自动更新控制工具,有需要的可... 目录设计原理与技术实现系统架构概述数学建模工具界面完整代码实现技术深度分析多层级控制理论服务层控制注

Java中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例解析

《Java中的分布式系统开发基于Zookeeper与Dubbo的应用案例解析》本文将通过实际案例,带你走进基于Zookeeper与Dubbo的分布式系统开发,本文通过实例代码给大家介绍的非常详... 目录Java 中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例一、分布式系统中的挑战二

基于Go语言开发一个 IP 归属地查询接口工具

《基于Go语言开发一个IP归属地查询接口工具》在日常开发中,IP地址归属地查询是一个常见需求,本文将带大家使用Go语言快速开发一个IP归属地查询接口服务,有需要的小伙伴可以了解下... 目录功能目标技术栈项目结构核心代码(main.go)使用方法扩展功能总结在日常开发中,IP 地址归属地查询是一个常见需求:

Nginx屏蔽服务器名称与版本信息方式(源码级修改)

《Nginx屏蔽服务器名称与版本信息方式(源码级修改)》本文详解如何通过源码修改Nginx1.25.4,移除Server响应头中的服务类型和版本信息,以增强安全性,需重新配置、编译、安装,升级时需重复... 目录一、背景与目的二、适用版本三、操作步骤修改源码文件四、后续操作提示五、注意事项六、总结一、背景与

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2