来写一个属于自己的Web服务器(上)

简介: 万维网(英语:World Wide Web),亦作“WWW”、“Web”,是一个透过互联网访问的,由许多互相链接的超文本组成的系统。—— 维基百科


前言


什么是Web,维基百科的描述如下:

万维网(英语:World Wide Web),亦作“WWW”、“Web”,是一个透过互联网访问的,由许多互相链接的超文本组成的系统。

—— 维基百科

我们的生活现在已经离不开互联网,我们日常使用的互联网服务中,其中的相当的一部分是Web系统所提供的,我们每天使用的搜索,新闻,购物等服务,其背后的实现,也是基于Web的技术栈,但是,Web系统究竟是怎么运作的呢?接下来我们就一起来实现一个最简单的Web服务器(使用python3),我们这里说的Web服务器是指HTTP服务器。


2

socket

socket是一种操作系统提供的进程间通信机制,简单来讲,socket是用来通信用的,它实现了TCP与UDP协议,Web系统是基于HTTP协议的,所以这里,我们使用socket来实现一个简单的Web服务器。


3

使用Python来实现一个最简单的HTTP服务器

1、新建一个文件夹WebServer,并在该文件下新建一个文件server.py

2、打开该文件,写入以下代码:

# 导入socket包
import socket
# 服务器IP与端口
HttpPort = 18080
HttpHost = ('localhost', HttpPort)
# 头部信息
HttpResponseHeader = '''HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
'''
# Header与Body分隔符
LineSeparator = '
'
# HTTP响应
HttpResponseBody = ''
# 创建基于IPV4 TCP的socket
ServerSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# socket的绑定与监听
ServerSocket.bind(HttpHost)
ServerSocket.listen(100)
print("server is running")
# 处理客户端连接
while True:
    HttpResponseBody = '很开心遇见你 :)'
    Client, Address = ServerSocket.accept()
    Request = Client.recv(1024).decode(encoding='utf-8')
    Client.sendall((HttpResponseHeader + HttpResponseBody).encode(encoding='utf-8'))
    Client.close()


3、我们在该目录下打开shell,并输入以下命令:

python3 server.py

我们可以看到以下输出:


27.png

我们打开浏览器,并在地址栏输入http://127.0.0.1:18080,可以看到以下输出:


28.png


上面的这一段代码的效果,我们已经看到了,但是,这段代码究竟做了什么呢?

TCP是传输层的协议,HTTP是应用层的协议,HTTP协议基于TCP协议,我们通过socket,建立起了客户端到服务器的TCP连接,服务器先进行监听,客户端发起一个连接,服务器收到该连接请求之后并同意建立连接,之后客户端向服务端发起HTTP请求,我们的服务端对该HTTP请求进行一定的解析之后,发送响应给客户端,然后关闭连接,这就完成了一次HTTP请求。


4

实现解析URL参数与用户提交的表单

1、我们更新server.py的代码如下:

# 导入socket包
import socket
# 服务器IP与端口
HttpPort = 18080
HttpHost = ('localhost', HttpPort)
# 头部信息
HttpResponseHeader = '''HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
'''
# Header与Body分隔符
LineSeparator = '
'
# HTTP响应
HttpResponseBody = ''
# 创建基于IPV4 TCP的socket
ServerSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# socket的绑定与监听
ServerSocket.bind(HttpHost)
ServerSocket.listen(100)
print("server is running at http://localhost:%d" % HttpPort)
# 获取HTTP请求报头
def get_headers(request):
# 分隔符切割
headers_array = request.split('
')
# HTTP请求头首行 是请求方法 请求路径 HTTP协议版本
headers = {}
for header_item in headers_array[1:]:
item_ = header_item.split(': ')
headers[item_[0]] = item_[1]
return headers
# 获取URL参数
def get_get_args(request_url):
get_args_arr = request_url[request_url.find('?')+1:].split('&')
# print(get_args_arr)
get_args = {}
try:
for get_item in get_args_arr:
item_ = get_item.split('=')
get_args[item_[0]] = item_[1]
return get_args
except:
return {}
# 获取POST表单参数
def get_post_args(request_body):
post_args_arr = request_body.split('&')
post_args = {}
for post_item in post_args_arr:
item_ = post_item.split('=')
post_args[item_[0]] = item_[1]
return post_args
# 处理客户端连接
while True:
Client, Address = ServerSocket.accept()
# 客户端的HTTP请求
Request = Client.recv(1024).decode(encoding='utf-8')
# 将请求分为报头与主体
RequestText = Request.split(LineSeparator)
# 报头
RequestHeader = RequestText[0]
# 主体
RequestBody = RequestText[1]
# 请求方法
RequestMethod = RequestHeader.split(' ')[0]
# 请求路径
RequestUrl = RequestHeader.split(' ')[1]
# 请求头部
RequestHeaders = get_headers(RequestHeader)
# 响应清空
HttpResponseBody = ''
# GET请求处理
if RequestMethod == 'GET':
HttpResponseBody += '''<html>
Your method is GET and your request url is ''' + RequestUrl + '''
<br>
The following are you headers :<br>
'''
for item in RequestHeaders.items():
HttpResponseBody += ('key :' + item[0] + ",value :" + item[1] + '<br>')
HttpResponseBody += 'There are your url args :<br>'
URL_args = get_get_args(RequestUrl)
for item in URL_args.items():
HttpRes

2、然后执行: python3 server.py


29.png


3、我们可以看到能够如下显示:

GET请求:


30.jpg


POST请求:

31.jpg


这里我们主要是对参数进行了解析,然后并对其进行了显示,现实中,我们使用搜索引擎的时候,关键字一般都是通过GET方法来加上参数,需要用户提交用户名密码或者其他表单时,我们一般使用POST方法,有关更多的HTTP资料,请参考这里MDN 。

相关文章
|
1月前
|
Java PHP
PHP作为广受青睐的服务器端脚本语言,在Web开发中占据重要地位。理解其垃圾回收机制有助于开发高效稳定的PHP应用。
【10月更文挑战第1天】PHP作为广受青睐的服务器端脚本语言,在Web开发中占据重要地位。其垃圾回收机制包括引用计数与循环垃圾回收,对提升应用性能和稳定性至关重要。本文通过具体案例分析,详细探讨PHP垃圾回收机制的工作原理,特别是如何解决循环引用问题。在PHP 8中,垃圾回收机制得到进一步优化,提高了效率和准确性。理解这些机制有助于开发高效稳定的PHP应用。
41 3
|
3月前
|
JavaScript 搜索推荐 前端开发
从零搭建到部署:Angular与Angular Universal手把手教你实现服务器端渲染(SSR),全面解析及实战指南助你提升Web应用性能与SEO优化效果
【8月更文挑战第31天】服务器端渲染(SSR)是现代Web开发的关键技术,能显著提升SEO效果及首屏加载速度,改善用户体验。Angular Universal作为官方SSR解决方案,允许在服务器端生成静态HTML文件。本文通过具体示例详细介绍如何使用Angular Universal实现SSR,并分享最佳实践。首先需安装Node.js和npm。
61 1
|
3月前
|
API C# 开发框架
WPF与Web服务集成大揭秘:手把手教你调用RESTful API,客户端与服务器端优劣对比全解析!
【8月更文挑战第31天】在现代软件开发中,WPF 和 Web 服务各具特色。WPF 以其出色的界面展示能力受到欢迎,而 Web 服务则凭借跨平台和易维护性在互联网应用中占有一席之地。本文探讨了 WPF 如何通过 HttpClient 类调用 RESTful API,并展示了基于 ASP.NET Core 的 Web 服务如何实现同样的功能。通过对比分析,揭示了两者各自的优缺点:WPF 客户端直接处理数据,减轻服务器负担,但需处理网络异常;Web 服务则能利用服务器端功能如缓存和权限验证,但可能增加服务器负载。希望本文能帮助开发者根据具体需求选择合适的技术方案。
141 0
|
3月前
|
Rust 安全 开发者
惊爆!Xamarin 携手机器学习,开启智能应用新纪元,个性化体验与跨平台优势完美融合大揭秘!
【8月更文挑战第31天】随着互联网的发展,Web应用对性能和安全性要求不断提高。Rust凭借卓越的性能、内存安全及丰富生态,成为构建高性能Web服务器的理想选择。本文通过一个简单示例,展示如何使用Rust和Actix-web框架搭建基本Web服务器,从创建项目到运行服务器全程指导,帮助读者领略Rust在Web后端开发中的强大能力。通过实践,读者可以体验到Rust在性能和安全性方面的优势,以及其在Web开发领域的巨大潜力。
38 0
|
3月前
|
Java 数据库 API
JSF与JPA的史诗级联盟:如何编织数据持久化的华丽织锦,重塑Web应用的荣耀
【8月更文挑战第31天】JavaServer Faces (JSF) 和 Java Persistence API (JPA) 分别是构建Java Web应用的用户界面组件框架和持久化标准。结合使用JSF与JPA,能够打造强大的数据驱动Web应用。首先,通过定义实体类(如`User`)和配置`persistence.xml`来设置JPA环境。然后,在JSF中利用Managed Bean(如`UserBean`)管理业务逻辑,通过`EntityManager`执行数据持久化操作。
51 0
|
3月前
|
JavaScript 前端开发 UED
服务器端渲染新浪潮:用Vue.js和Nuxt.js构建高性能Web应用
【8月更文挑战第30天】在现代Web开发中,提升应用性能和SEO友好性是前端开发者面临的挑战。服务器端渲染(SSR)能加快页面加载速度并改善搜索引擎优化。Vue.js结合Nuxt.js提供了一个高效框架来创建SSR应用。通过安装`create-nuxt-app`,可以轻松创建新的Nuxt.js项目,并利用其自动路由功能简化页面管理。Nuxt.js默认采用SSR模式,并支持通过`asyncData`方法预取数据,同时提供了静态站点生成和服务器端渲染的部署选项,显著提升用户体验。
77 0
|
3月前
|
数据可视化 Python
通过python建立一个web服务查看服务器上的文本、图片、视频等文件
通过python建立一个web服务查看服务器上的文本、图片、视频等文件
61 0
|
4天前
|
弹性计算
阿里云2核16G服务器多少钱一年?亲测价格查询1个月和1小时收费标准
阿里云2核16G服务器提供多种ECS实例规格,内存型r8i实例1年6折优惠价为1901元,按月收费334.19元,按小时收费0.696221元。更多规格及详细报价请访问阿里云ECS页面。
37 9
|
1天前
|
监控 Ubuntu Linux
使用VSCode通过SSH远程登录阿里云Linux服务器异常崩溃
通过 VSCode 的 Remote - SSH 插件远程连接阿里云 Ubuntu 22 服务器时,会因高 CPU 使用率导致连接断开。经排查发现,VSCode 连接根目录 ".." 时会频繁调用"rg"(ripgrep)进行文件搜索,导致 CPU 负载过高。解决方法是将连接目录改为"root"(或其他具体的路径),避免不必要的文件检索,从而恢复正常连接。
|
5天前
|
弹性计算 异构计算
2024年阿里云GPU服务器多少钱1小时?亲测价格查询方法
2024年阿里云GPU服务器每小时收费因实例规格不同而异。可通过阿里云GPU服务器页面选择“按量付费”查看具体价格。例如,NVIDIA A100的gn7e实例为34.742元/小时,NVIDIA A10的gn7i实例为12.710156元/小时。更多详情请访问阿里云官网。
34 2