一、静态web服务器-多任务

多任务web服务器:使用多线程,比进程更节省资源,支持多用户同时访问,可以同时处理多个客户端请求

  • 实现步骤

    • 若客户端与服务端建立连接,则创建子线程,使用子线程处理客户端请求,防止主线程阻塞
    • 将创建的子线程设置为守护主线程,防止主线程无法退出

实现代码

import socket
import threading
def handle_client_request(comm_socket):    # 处理客户端请求recv_data = comm_socket.recv(4096)  # 接收请求的二进制数据if len(recv_data) == 0:print('未获取到请求数据!')comm_socket.close()returnrecv_content = recv_data.decode('utf-8')  # 对二进制数据解码print('获取到的数据内容为:', recv_content)request_list = recv_content.split(" ", maxsplit=2)  # 根据指定字符串空格进行分割,最大分割次数为2request_path = request_list[1]  # 获取请求资源路径print('请求路径为:', request_path)if request_path == "/":  # 判断请求的是否是根目录,若是则返回首页指定数据request_path = "/index.html"try:with open('C:/Users/username/Desktop/ubuntu' + request_path, 'rb') as file:  # 动态打开指定文件file_data = file.read()  # 读取指定文件数据except Exception as e:  # 请求异常,资源不存在,返回指定404错误数据with open('C:/Users/username/Desktop/ubuntu/error.html', 'rb') as file:  # 打开指定错误文件error_data = file.read()  # 读取指定错误数据response_line = "HTTP/1.1 404 Not Found!!\r\n"  # 响应行response_header = "Server: PWS1.0 服务器名称及版本……\r\n"  # 响应头response_body = error_data  # 响应体response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body  # 拼接响应报文comm_socket.send(response_data)  # 发送数据给浏览器else:response_line = "HTTP/1.1 200 OK # 成功!!\r\n"response_header = "Server: PWS1.0 # 服务器名称版本!\r\n"response_body = file_dataresponse_data = (response_line + response_header + '\r\n').encode('utf-8') + response_bodycomm_socket.send(response_data)finally:comm_socket.close()  # 关闭服务于客户端的套接字def main():server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    # 创建TCP服务端套接字server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)   # 设置端口号复用,程序退出端口号立即释放server_socket.bind(("", 9000))   # 绑定端口号server_socket.listen(128)   # 设置监听while True:comm_socket, ip_port = server_socket.accept()   # 等待接受客户端连接请求thread = threading.Thread(target=handle_client_request, args=(comm_socket,))  # 若客户端和服务器连接成功,创建子线程thread.setDaemon(True)   # 设置守护主线程thread.start()   # 启动子线程执行对应任务if __name__ == '__main__':main()

输出如下

获取到的数据内容为: GET /index.html HTTP/1.1
Host: 127.0.0.1:9000
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: csrftoken=1wb7v0r0BQuokJCxRS4JAO2XApvrHXFP90t2PiYb0mz7AwWS0NoKTi0zNaIjOfTl; Hm_lvt_18f619820855042bca58b32408f44de7=1658219884请求路径为: /index.html

浏览器响应如下

二、静态web服务器-面向对象

  • 实现步骤

    • 把提供服务的web服务器抽象为一个类
    • 提供web服务器初始化方法,在方法中创建socket对象
    • 提供一个开启web服务器的方法,让web服务器处理客户端请求操作

实现代码

import socket
import threading
class HttpWebServer(object):   # 定义web服务器类,将提供服务的web服务器抽象为一个类def __init__(self):   # 初始化服务端套接字server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    # 创建TCP套接字server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)  # 设置端口复用,程序退出端口号立即释放server_socket.bind(("", 9000))     # 绑定端口号server_socket.listen(128)    # 设置监听self.server_socket = server_socket@staticmethoddef handle_client_request(comm_socket):recv_data = comm_socket.recv(4096)  # 接收请求的二进制数据if len(recv_data) == 0:print('未获取到请求数据!')comm_socket.close()returnrecv_content = recv_data.decode('utf-8')  # 对二进制数据解码print('获取到的数据内容为:', recv_content)request_list = recv_content.split(" ", maxsplit=2)  # 根据指定字符串空格进行分割,最大分割次数为2request_path = request_list[1]  # 获取请求资源路径print('请求路径为:', request_path)if request_path == "/":  # 判断请求的是否是根目录,若是则返回首页指定数据request_path = "/index.html"try:with open('C:/Users/熊世强/Desktop/ubuntu' + request_path, 'rb') as file:  # 动态打开指定文件file_data = file.read()  # 读取指定文件数据except Exception as e:  # 请求异常,资源不存在,返回指定404错误数据with open('C:/Users/熊世强/Desktop/ubuntu/error.html', 'rb') as file:  # 打开指定错误文件error_data = file.read()  # 读取指定错误数据response_line = "HTTP/1.1 404 Not Found!!\r\n"  # 响应行response_header = "Server: PWS1.0 服务器名称及版本……\r\n"  # 响应头response_body = error_data  # 响应体response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body  # 拼接响应报文comm_socket.send(response_data)  # 发送数据给浏览器else:response_line = "HTTP/1.1 200 OK # 成功!!\r\n"response_header = "Server: PWS1.0 # 服务器名称版本!\r\n"response_body = file_dataresponse_data = (response_line + response_header + '\r\n').encode('utf-8') + response_bodycomm_socket.send(response_data)finally:comm_socket.close()  # 关闭服务于客户端的套接字def start(self):   # 启动web服务器while True:comm_socket, ip_port = self.server_socket.accept()   # 等待接收客户端连接请求thread = threading.Thread(target=self.handle_client_request, args=(comm_socket,))   # 若客户端和服务器建立连接,则创建子线程thread.setDaemon(True)   # 设置守护子线程thread.start()   # 启动子线程执行对应任务def main():   # 程序入口函数webServer = HttpWebServer()   # 创建web服务器对象webServer.start()   # 启动web服务器进行工作if __name__ == '__main__':main()

输出如下

获取到的数据内容为: GET /index.html HTTP/1.1
Host: 127.0.0.1:9000
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: csrftoken=1wb7v0r0BQuokJCxRS4JAO2XApvrHXFP90t2PiYb0mz7AwWS0NoKTi0zNaIjOfTl; Hm_lvt_18f619820855042bca58b32408f44de7=1658219884请求路径为: /index.html

浏览器响应如下

三、静态web服务器-命令行启动动态绑定端口号

  • 实现步骤

    • 获取执行python程序的终端命令行参数
    • 判断参数类型,设置端口号必须是整型
    • 为web服务器类的初始化方法添加一个端口号参数,用于绑定端口号

实现代码

import socket
import threading
import sys
class HttpWebServer(object):   # 定义web服务器类,将提供服务的web服务器抽象为一个类def __init__(self, port):   # 初始化服务端套接字,添加端口号参数server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    # 创建TCP套接字server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)  # 设置端口复用,程序退出端口号立即释放server_socket.bind(("", port))     # 绑定端口号server_socket.listen(128)    # 设置监听self.server_socket = server_socket@staticmethoddef handle_client_request(comm_socket):   # 处理客户端请求recv_data = comm_socket.recv(4096)  # 接收请求的二进制数据if len(recv_data) == 0:print('未获取到请求数据!')comm_socket.close()returnrecv_content = recv_data.decode('utf-8')  # 对二进制数据解码print('获取到的数据内容为:', recv_content)request_list = recv_content.split(" ", maxsplit=2)  # 根据指定字符串空格进行分割,最大分割次数为2request_path = request_list[1]  # 获取请求资源路径print('请求路径为:', request_path)if request_path == "/":  # 判断请求的是否是根目录,若是则返回首页指定数据request_path = "/index.html"try:with open('C:/Users/username/Desktop/ubuntu' + request_path, 'rb') as file:  # 动态打开指定文件file_data = file.read()  # 读取指定文件数据except Exception as e:  # 请求异常,资源不存在,返回指定404错误数据with open('C:/Users/username/Desktop/ubuntu/error.html', 'rb') as file:  # 打开指定错误文件error_data = file.read()  # 读取指定错误数据response_line = "HTTP/1.1 404 Not Found!!\r\n"  # 响应行response_header = "Server: PWS1.0 服务器名称及版本……\r\n"  # 响应头response_body = error_data  # 响应体response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body  # 拼接响应报文comm_socket.send(response_data)  # 发送数据给浏览器else:response_line = "HTTP/1.1 200 OK # 成功!!\r\n"response_header = "Server: PWS1.0 # 服务器名称版本!\r\n"response_body = file_dataresponse_data = (response_line + response_header + '\r\n').encode('utf-8') + response_bodycomm_socket.send(response_data)finally:comm_socket.close()  # 关闭服务于客户端的套接字def start(self):   # 启动web服务器while True:comm_socket, ip_port = self.server_socket.accept()   # 等待接收客户端连接请求thread = threading.Thread(target=self.handle_client_request, args=(comm_socket,))   # 若客户端和服务器建立连接,则创建子线程thread.setDaemon(True)   # 设置守护子线程thread.start()   # 启动子线程执行对应任务def main():   # 程序入口函数print('命令行输入的参数为:', sys.argv)if len(sys.argv) != 2:    # 判断命令行参数个数是否为2print("请执行格式为[ python3 xx.py 9000 ] 的命令")returnif not sys.argv[1].isdigit():   # 判断字符串是否为数字组成,必须为整型print("请执行格式为[ python3 xx.py 9000 ]的命令")returnport = int(sys.argv[1])   # 获取终端命令行参数web_server = HttpWebServer(port)web_server.start()if __name__ == '__main__':main()

命令行执行

 浏览器响应如下 

学习导航:http://xqnav.top/

python多任务、面向对象、命令行启动动态绑定端口号静态web服务器代码实现相关推荐

  1. ipad pro python xcode_从命令行启动Xcode模拟器

    一.Xcode允许我们使用xcrun命令运行模拟器 1.列出你安装的所有可用的设备 xcrun instruments -s 终端显示结果: Apple TV (11.2) [E08E425C-ACE ...

  2. Python基础 3.4 HTTP协议和静态Web服务器

    HTTP协议和静态Web服务器 3.4.1 HTTP协议 1.HTTP协议介绍 全程:超文本传输协议 作用:规定浏览器和web服务器通信的数据格式 HTTP协议是在应用层的协议,基于传输层的TCP传输 ...

  3. Python 高级:05 HTTP 协议和静态 Web 服务器

    一.HTTP 协议 1. HTTP 协议的介绍 HTTP 协议的全称是(Hyper Text Transfer Protocol),翻译过来就是超文本传输协议.超文本就是超级文本的缩写,是指超越文本限 ...

  4. python-windows命令行启动appium及杀掉对应接口进程

    文章目录 windows命令行启动appium及杀掉对应接口进程 一.环境配置 1.安装命令行版appium 2.安装appium-doctor检测 3.python安装Appium-Python-C ...

  5. 如何设置Fedora默认从命令行启动?

    2019独角兽企业重金招聘Python工程师标准>>> Sumary:因为在Fedora中没有/etc/initab文件我们不方便从这里设置它的runlevel target,但是L ...

  6. vscode linux命令行启动,在命令行启动vscode

    1.windows使用 code . 命令打开vscode 1.打开vscode安装位置,进入bin文件夹,复制路径 eg:E:\Microsoft VS Code\bin: 2.回到桌面,右键我的电 ...

  7. mysql 前台启动_从Windows命令行启动MySQL

    可以从命令行手动启动MySQL服务器.可以在任何版本的Windows中实现. 要想从命令行启动mysqld服务器,你应当启动控制台窗口(或"DOS window")并输入命令: C ...

  8. Android AM命令行启动程序的方法

    在Android中,除了从界面上启动程序之外,还可以从命令行启动程序,使用的是命令行工具am. 启动的方法为 wangwei@wwG41D3:~$ adb shell       $ su # am ...

  9. Linux设置界面或命令行启动

    设置界面或命令行启动 以root的身份登陆,然后执行: #cd /etc #vi inittab 更改"id:5:initdefault:"语句即可. 其中5表示默认图形启动界面 ...

最新文章

  1. 为了控制Bean的加载我使出了这些杀手锏
  2. minigui linux 安装与运行
  3. Genymotion设置代理至BurpSuite和Charles
  4. 详细解读神经网络十大误解,再也不会弄错它的工作原理
  5. intent隐式和显式_Neo4j:使隐式关系成为显式和双向关系
  6. React开发(150):注意定义数组格式
  7. redis:Invalid input of type: 'bool' type. Convert to a byte,string or number first
  8. LLE(局部线性嵌入)matlab代码实现
  9. 新特性 | Java8 的这个特性,用起来真的很爽!
  10. python爬取正确但不出文件_使用Python爬取微信公众号文章并保存为PDF文件(解决图片不显示的问题)...
  11. 阅面携手英特尔发布“繁星”系列产品,推动机器视觉迈入AI芯片新纪元
  12. xampp 403 禁止访问 问题解决
  13. 2021最新阿里代码规范(前端篇)
  14. 新能源汽车动力电池(热管理)热流体仿真分析-基于SCDM和STAR-CCM+热仿真分析课程(评论发链接)
  15. 掘金夜谈-畅聊程序人生(笔记)
  16. asp微信扫码签到源码
  17. Java之父詹姆斯·高斯林 (James Gosling)学鸿蒙(HarmonyOS),HarmonyOS(鸿蒙)——Image组件详述
  18. 感谢星球日报、陀螺财经小伙伴的肯定,我们会继续努力哒
  19. 数据仓库Kimball Or Inmon?
  20. 联发科中端芯片策略为何未能拯救业绩?

热门文章

  1. 20140322 卡迪夫城VS利物浦,拔出重剑,有惊无险
  2. 职场健康:久坐不动最伤五部位 简单动作可有效改善
  3. 牛客算法課 (算法入門班) 貪心與模擬(4)
  4. 【Google Play】创建和管理内部测试版本 ( 创建内部测试版本 | 检查并发布内部测试版本 )
  5. RHCE 第十一天 mail postfix dovecot SSL
  6. ESP8266断网后自动重新连接Wi-Fi网络
  7. 什么是token?Android中token的使用讲解
  8. 我的洛谷冬日绘板计划
  9. thinkpad x1c 2015使用GPT分区方式安装原版win7系统
  10. cast from pointer to smaller type ‘int‘ loses information —— NDK 开发