【从零学习python 】87. 手动搭建HTTP服务器的Python实现及多线程并发处理

简介: 【从零学习python 】87. 手动搭建HTTP服务器的Python实现及多线程并发处理

导入必要的模块

import re
import socket
from multiprocessing import Process

我们导入了re模块用于正则表达式操作,socket模块用于网络通信,以及multiprocessing模块中的Process类用于创建子进程

定义WSGIServer类

class WSGIServer():
    def __init__(self, server, port, root):
        self.server = server
        self.port = port
        self.root = root
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server_socket.bind((self.server, self.port))
        self.server_socket.listen(128)

在类的初始化方法__init__中,我们传入了服务器地址server、端口号port和根目录root作为参数,然后创建了一个socket对象server_socket,并设置了一些属性。我们通过bind方法将服务器地址和端口号绑定到server_socket上,并调用listen方法监听连接请求。

处理客户端请求

def handle_socket(self, socket):
    data = socket.recv(1024).decode('utf-8').splitlines()[0]
    file_name = re.match(r'[^/]+(/[^ ]*)', data)[1]
    if file_name == '/':
        file_name = self.root + '/index.html'
    else:
        file_name = self.root + file_name
    try:
        file = open(file_name, 'rb')
    except IOError:
        response_header = 'HTTP/1.1 404 NOT FOUND \r\n'
        response_header += '\r\n'
        response_body = '========Sorry,file not found======='.encode('utf-8')
    else:
        response_header = 'HTTP/1.1 200 OK \r\n'
        response_header += '\r\n'
        response_body = file.read()
    finally:
        socket.send(response_header.encode('utf-8'))
        socket.send(response_body)

接下来定义了一个handle_socket方法,用于处理客户端发来的请求。首先,我们通过socket.recv方法接收请求数据,并对数据进行解码。然后,使用正则表达式从请求数据中提取出文件名。如果文件名为根目录’/',我们将其设置为根目录下的’index.html’文件,否则拼接上根目录路径。然后,尝试打开对应的文件,如果文件不存在,我们返回404状态码和错误提示信息;如果文件存在,我们返回200状态码和文件内容作为响应体。

最后,我们通过finally块使用socket.send方法将响应头和响应体发送给客户端。

持续监听连接请求

def forever_run(self):
    while True:
        client_socket, client_addr = self.server_socket.accept()
        p = Process(target=self.handle_socket, args=(client_socket,))
        p.start()
        client_socket.close()

在WSGIServer类中,定义了一个forever_run方法,用于持续监听连接请求。在循环中,我们使用accept方法接受客户端的连接请求,并创建一个子进程Process去处理连接请求,以实现多线程并发处理。然后关闭客户端套接字。

主程序入口

if __name__ == '__main__':
    ip = '0.0.0.0'
    port = 8899
    server = WSGIServer(ip, port, './pages')
    print('server is running at {}:{}'.format(ip, port))
    server.forever_run()

在主程序中,我们实例化了WSGIServer类,并传入服务器地址、端口号和根目录的参数。然后打印出服务器运行的信息,最后调用forever_run方法开始监听连接请求。

相关文章
|
5天前
|
Python
python3多线程中使用线程睡眠
本文详细介绍了Python3多线程编程中使用线程睡眠的基本方法和应用场景。通过 `time.sleep()`函数,可以使线程暂停执行一段指定的时间,从而控制线程的执行节奏。通过实际示例演示了如何在多线程中使用线程睡眠来实现计数器和下载器功能。希望本文能帮助您更好地理解和应用Python多线程编程,提高程序的并发能力和执行效率。
34 20
|
18天前
|
并行计算 安全 Java
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
在Python开发中,GIL(全局解释器锁)一直备受关注。本文基于CPython解释器,探讨GIL的技术本质及其对程序性能的影响。GIL确保同一时刻只有一个线程执行代码,以保护内存管理的安全性,但也限制了多线程并行计算的效率。文章分析了GIL的必要性、局限性,并介绍了多进程、异步编程等替代方案。尽管Python 3.13计划移除GIL,但该特性至少要到2028年才会默认禁用,因此理解GIL仍至关重要。
95 16
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
|
1月前
|
数据可视化 数据挖掘 大数据
1.1 学习Python操作Excel的必要性
学习Python操作Excel在当今数据驱动的商业环境中至关重要。Python能处理大规模数据集,突破Excel行数限制;提供丰富的库实现复杂数据分析和自动化任务,显著提高效率。掌握这项技能不仅能提升个人能力,还能为企业带来价值,减少人为错误,提高决策效率。推荐从基础语法、Excel操作库开始学习,逐步进阶到数据可视化和自动化报表系统。通过实际项目巩固知识,关注新技术,为职业发展奠定坚实基础。
|
2月前
|
Python
Python学习的自我理解和想法(10)
这是我在千锋教育B站课程学习Python的第10天笔记,主要学习了函数的相关知识。内容包括函数的定义、组成、命名、参数分类(必须参数、关键字参数、默认参数、不定长参数)及调用注意事项。由于开学时间有限,记录较为简略,望谅解。通过学习,我理解了函数可以封装常用功能,简化代码并便于维护。若有不当之处,欢迎指正。
|
2月前
|
Python 容器
Python学习的自我理解和想法(9)
这是我在B站跟随千锋教育学习Python的第9天,主要学习了赋值、浅拷贝和深拷贝的概念及其底层逻辑。由于开学时间紧张,内容较为简略,但希望能帮助理解这些重要概念。赋值是创建引用,浅拷贝创建新容器但元素仍引用原对象,深拷贝则创建完全独立的新对象。希望对大家有所帮助,欢迎讨论。
|
2月前
|
存储 安全 索引
Python学习的自我理解和想法(8)
这是我在B站千锋教育学习Python的第8天,主要内容是元组。元组是一种不可变的序列数据类型,用于存储一组有序的元素。本文介绍了元组的基本操作,包括创建、访问、合并、切片、遍历等,并总结了元组的主要特点,如不可变性、有序性和可作为字典的键。由于开学时间紧张,内容较为简略,望见谅。
|
2月前
|
Python
Python学习的自我理解和想法(7)
学的是b站的课程(千锋教育),跟老师写程序,不是自创的代码! 今天是学Python的第七天,学的内容是集合。开学了,时间不多,写得不多,见谅。
|
2月前
|
存储 索引 Python
Python学习的自我理解和想法(6)
这是我在B站千锋教育学习Python的第6天笔记,主要学习了字典的使用方法,包括字典的基本概念、访问、修改、添加、删除元素,以及获取字典信息、遍历字典和合并字典等内容。开学后时间有限,内容较为简略,敬请谅解。
|
2月前
|
索引 Python
Python学习的自我理解和想法(5)
这是我在B站千锋教育学习Python的第五天笔记,主要内容包括列表的操作,如排序(`sort()`、``sorted()``)、翻转(`reverse()`)、获取长度(`len()`)、最大最小值(`max()`、``min()``)、索引(`index()`)、嵌套列表和列表生成(`range`、列表生成式)。通过这些操作,可以更高效地处理数据。希望对大家有所帮助!
|
2月前
|
存储 索引 Python
Python学习的自我理解和想法(4)
今天是学习Python的第四天,主要学习了列表。列表是一种可变序列类型,可以存储任意类型的元素,支持索引和切片操作,并且有丰富的内置方法。主要内容包括列表的入门、关键要点、遍历、合并、判断元素是否存在、切片、添加和删除元素等。通过这些知识点,可以更好地理解和应用列表这一强大的数据结构。

推荐镜像

更多