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

相关文章

基于 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

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

Linux搭建ftp服务器的步骤

《Linux搭建ftp服务器的步骤》本文给大家分享Linux搭建ftp服务器的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录ftp搭建1:下载vsftpd工具2:下载客户端工具3:进入配置文件目录vsftpd.conf配置文件4:

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat

基于Java开发一个极简版敏感词检测工具

《基于Java开发一个极简版敏感词检测工具》这篇文章主要为大家详细介绍了如何基于Java开发一个极简版敏感词检测工具,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录你是否还在为敏感词检测头疼一、极简版Java敏感词检测工具的3大核心优势1.1 优势1:DFA算法驱动,效率提升10

Linux查询服务器 IP 地址的命令详解

《Linux查询服务器IP地址的命令详解》在服务器管理和网络运维中,快速准确地获取服务器的IP地址是一项基本但至关重要的技能,下面我们来看看Linux中查询服务器IP的相关命令使用吧... 目录一、hostname 命令:简单高效的 IP 查询工具命令详解实际应用技巧注意事项二、ip 命令:新一代网络配置全

Python开发简易网络服务器的示例详解(新手入门)

《Python开发简易网络服务器的示例详解(新手入门)》网络服务器是互联网基础设施的核心组件,它本质上是一个持续运行的程序,负责监听特定端口,本文将使用Python开发一个简单的网络服务器,感兴趣的小... 目录网络服务器基础概念python内置服务器模块1. HTTP服务器模块2. Socket服务器模块