【从零学习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方法开始监听连接请求。

相关文章
|
1月前
|
并行计算 Java 数据处理
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
155 0
|
23天前
|
安全
List并发线程安全问题
【10月更文挑战第21天】`List` 并发线程安全问题是多线程编程中一个非常重要的问题,需要我们认真对待和处理。只有通过不断地学习和实践,我们才能更好地掌握多线程编程的技巧和方法,提高程序的性能和稳定性。
130 59
|
24天前
|
数据采集 前端开发 算法
Python Requests 的高级使用技巧:应对复杂 HTTP 请求场景
本文介绍了如何使用 Python 的 `requests` 库应对复杂的 HTTP 请求场景,包括 Spider Trap(蜘蛛陷阱)、SESSION 访问限制和请求频率限制。通过代理、CSS 类链接数控制、多账号切换和限流算法等技术手段,提高爬虫的稳定性和效率,增强在反爬虫环境中的生存能力。文中提供了详细的代码示例,帮助读者掌握这些高级用法。
Python Requests 的高级使用技巧:应对复杂 HTTP 请求场景
|
7天前
|
JSON API 数据格式
Python中获取HTTP请求响应体的详解
本文介绍了如何使用Python的`requests`和`urllib`库发送HTTP请求并处理响应体。`requests`库简化了HTTP请求过程,适合快速开发;`urllib`库则更为底层,适用于性能要求较高的场景。文章详细演示了发送GET请求、处理JSON响应等常见操作。
|
11天前
|
API 数据处理 Python
探秘Python并发新世界:asyncio库,让你的代码并发更优雅!
在Python编程中,随着网络应用和数据处理需求的增长,并发编程变得愈发重要。asyncio库作为Python 3.4及以上版本的标准库,以其简洁的API和强大的异步编程能力,成为提升性能和优化资源利用的关键工具。本文介绍了asyncio的基本概念、异步函数的定义与使用、并发控制和资源管理等核心功能,通过具体示例展示了如何高效地编写并发代码。
23 2
|
14天前
|
存储 设计模式 分布式计算
Java中的多线程编程:并发与并行的深度解析####
在当今软件开发领域,多线程编程已成为提升应用性能、响应速度及资源利用率的关键手段之一。本文将深入探讨Java平台上的多线程机制,从基础概念到高级应用,全面解析并发与并行编程的核心理念、实现方式及其在实际项目中的应用策略。不同于常规摘要的简洁概述,本文旨在通过详尽的技术剖析,为读者构建一个系统化的多线程知识框架,辅以生动实例,让抽象概念具体化,复杂问题简单化。 ####
|
1月前
|
Python
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
使用Python的socket库实现客户端到服务器端的图片传输,包括客户端和服务器端的代码实现,以及传输结果的展示。
138 3
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
|
1月前
|
JSON 数据格式 Python
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
本文介绍了如何使用Python的socket模块实现客户端到服务器端的文件传输,包括客户端发送文件信息和内容,服务器端接收并保存文件的完整过程。
147 1
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
|
20天前
|
数据库 开发者 Python
“Python异步编程革命:如何从编程新手蜕变为并发大师,掌握未来技术的制胜法宝”
【10月更文挑战第25天】介绍了Python异步编程的基础和高级技巧。文章从同步与异步编程的区别入手,逐步讲解了如何使用`asyncio`库和`async`/`await`关键字进行异步编程。通过对比传统多线程,展示了异步编程在I/O密集型任务中的优势,并提供了最佳实践建议。
16 1
|
1月前
|
Java Maven Kotlin
vertx的学习总结7之用kotlin 与vertx搞一个简单的http
本文介绍了如何使用Kotlin和Vert.x创建一个简单的HTTP服务器,包括设置路由、处理GET和POST请求,以及如何使用HTML表单发送数据。
33 2
vertx的学习总结7之用kotlin 与vertx搞一个简单的http