创建web服务器

1 创建返回固定数据的web服务器:通过 localhost:8000/index.html 进行访问

import socketif __name__ == '__main__':# socket.AF_INET :IPv4 地址   socket.SOCK_STREAM:TCP链接tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 设置端口号复用 程序退出 端口号释放tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)# 绑定端口号tcp_server_socket.bind(('',8000))# 设置监听tcp_server_socket.listen(128)# 循环等待接收客户端的链接while True:# 等待客户端的链接请求new_socket,ip_prot = tcp_server_socket.accept()# 代码执行到此 说明链接成功# 接受客户端的请求消息recv_data = new_socket.recv(4096)print(recv_data)# 打开文件读取文件中的数据with open("index.html","r",encoding='utf-8') as file:# 读取文件file_data = file.read()# 设置响应行response_line = "HTTP/1.1 200 Ok\r\n"# 设置响应头response_Header = "Server:PWS/1.0\r\n"# 设置响应体response_body = file_data# 拼接 响应体response = response_line + response_Header + "\r\n" + response_body# 设置二级制数据response_data = response.encode('utf-8')# 给服务端响应数据new_socket.send(response_data)# 断开链接new_socket.close()

2 根据不同的请求 返回不同的数据

import socketif __name__ == '__main__':# socket.AF_INET :IPv4 地址   socket.SOCK_STREAM:TCP链接tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 设置端口号复用 程序退出 端口号释放tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)# 绑定端口号tcp_server_socket.bind(('',8000))# 设置监听tcp_server_socket.listen(128)# 循环等待接收客户端的链接while True:# 此刻代表链接成功new_socket, ip_prot = tcp_server_socket.accept()# 接收客户端发送的消息 接收过来的是二进制消息 需要进行解码recv_data = new_socket.recv(4096)# 对二进制消息进行解码  接收的是客户端 请求报文的消息recv_content = recv_data.decode('utf-8')print(recv_content)# 对请求报文的消息 进行截取 获取URL地址栏的信息request_list = recv_content.split(' ',maxsplit=2) # 根据空格截取 只截取最前面的两个request_path = request_list[1] # /index.html# 读取文件  rb 模式兼容图片等with open('./'+request_path,'rb',) as file:file_data = file.read()# 设置响应行response_line = 'HTTP/1.1 200 OK\r\n'# 设置响应头response_header = "Server:PWS/1.0\r\n"# 响应体response_body = file_data# 进行拼接 转化为二进制response = (response_line + response_header + "\r\n").encode('utf-8') + response_body# 给客户端响应消息new_socket.send(response)# 关闭链接new_socket.close()

3 处理发生错误的情况,比如访问的页面不存在返回404页面,比如 访问 /  返回index.html页面。

 

import socketdef main():# socket.AF_INET :IPv4 地址   socket.SOCK_STREAM:TCP链接tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 设置端口号复用 程序退出 端口号释放tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)# 绑定端口号tcp_server_socket.bind(('', 8000))# 设置监听tcp_server_socket.listen(128)# 循环等待接收客户端的链接while True:# 此刻代表链接成功new_socket, ip_prot = tcp_server_socket.accept()# 接收客户端发送的消息 接收过来的是二进制消息 需要进行解码recv_data = new_socket.recv(4096)# 判断接收的消息是否为空  如果是空的话就关闭链接if len(recv_data) == 0:new_socket.close()return# 对二进制消息进行解码  接收的是客户端 请求报文的消息recv_content = recv_data.decode('utf-8')print(recv_content)# 对请求报文的消息 进行截取 获取URL地址栏的信息request_list = recv_content.split(' ', maxsplit=2)  # 根据空格截取 只截取最前面的两个request_path = request_list[1]  # /index.html# 判断请求是否是跟目录 如果是返回index.htmlif request_path == "/":request_path = '/index.html'# 判断读取的文件是否存在 如果不存在返回 404 页面try:# 读取文件  rb 模式兼容图片等with open('./' + request_path, 'rb', ) as file:file_data = file.read()except Exception as e:with open("error.html",'rb') as file:file_data = file.read()# 设置响应行response_line = 'HTTP/1.1 200 OK\r\n'# 设置响应头response_header = "Server:PWS/1.0\r\n"# 响应体response_body = file_data# 进行拼接 转化为二进制response = (response_line + response_header + "\r\n").encode('utf-8') + response_body# 给客户端响应消息new_socket.send(response)else:# 设置响应行response_line = 'HTTP/1.1 200 OK\r\n'# 设置响应头response_header = "Server:PWS/1.0\r\n"# 响应体response_body = file_data# 进行拼接 转化为二进制response = (response_line + response_header + "\r\n").encode('utf-8') + response_body# 给客户端响应消息new_socket.send(response)finally:# 关闭链接new_socket.close()if __name__ == '__main__':main()

4  创建多线程web服务器 

import socket
import threadingdef handle_client_request(new_socket):recv_data = new_socket.recv(4096)if len(recv_data) == 0:new_socket.close()return# 对二进制消息进行解码  接收的是客户端 请求报文的消息recv_content = recv_data.decode('utf-8')print(recv_content)# 对请求报文的消息 进行截取 获取URL地址栏的信息request_list = recv_content.split(' ', maxsplit=2)  # 根据空格截取 只截取最前面的两个request_path = request_list[1]  # /index.html# 判断请求是否是跟目录 如果是返回index.htmlif request_path == "/":request_path = '/index.html'# 判断读取的文件是否存在 如果不存在返回 404 页面try:# 读取文件  rb 模式兼容图片等with open('./' + request_path, 'rb', ) as file:file_data = file.read()except Exception as e:with open("error.html", 'rb') as file:file_data = file.read()# 设置响应行response_line = 'HTTP/1.1 200 OK\r\n'# 设置响应头response_header = "Server:PWS/1.0\r\n"# 响应体response_body = file_data# 进行拼接 转化为二进制response = (response_line + response_header + "\r\n").encode('utf-8') + response_body# 给客户端响应消息new_socket.send(response)else:# 设置响应行response_line = 'HTTP/1.1 200 OK\r\n'# 设置响应头response_header = "Server:PWS/1.0\r\n"# 响应体response_body = file_data# 进行拼接 转化为二进制response = (response_line + response_header + "\r\n").encode('utf-8') + response_body# 给客户端响应消息new_socket.send(response)finally:# 关闭链接new_socket.close()def main():# socket.AF_INET :IPv4 地址   socket.SOCK_STREAM:TCP链接tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 设置端口号复用  当服务端断开  端口号 可以使用tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)# 绑定端口号tcp_server_socket.bind(('',8000))# 设置监听tcp_server_socket.listen(128)# 建立链接while True:new_socket, ip_prot = tcp_server_socket.accept()# 创建多线程sub_thread = threading.Thread(target=handle_client_request,args=(new_socket,))# 设置成为守护主线sub_thread.setDaemon(True)# 启动子线程sub_thread.start()if __name__ == '__main__':main()

5 使用类创建web服务器,创建一个处理数据的函数, 创建一个类(初始化websock,启动websocket)

import socket
import threadingdef handle_client_request(new_socket):recv_data = new_socket.recv(4096)if len(recv_data) == 0:new_socket.close()return# 对二进制消息进行解码  接收的是客户端 请求报文的消息recv_content = recv_data.decode('utf-8')print(recv_content)# 对请求报文的消息 进行截取 获取URL地址栏的信息request_list = recv_content.split(' ', maxsplit=2)  # 根据空格截取 只截取最前面的两个request_path = request_list[1]  # /index.html# 判断请求是否是跟目录 如果是返回index.htmlif request_path == "/":request_path = '/index.html'# 判断读取的文件是否存在 如果不存在返回 404 页面try:# 读取文件  rb 模式兼容图片等with open('./' + request_path, 'rb', ) as file:file_data = file.read()except Exception as e:with open("error.html", 'rb') as file:file_data = file.read()# 设置响应行response_line = 'HTTP/1.1 200 OK\r\n'# 设置响应头response_header = "Server:PWS/1.0\r\n"# 响应体response_body = file_data# 进行拼接 转化为二进制response = (response_line + response_header + "\r\n").encode('utf-8') + response_body# 给客户端响应消息new_socket.send(response)else:# 设置响应行response_line = 'HTTP/1.1 200 OK\r\n'# 设置响应头response_header = "Server:PWS/1.0\r\n"# 响应体response_body = file_data# 进行拼接 转化为二进制response = (response_line + response_header + "\r\n").encode('utf-8') + response_body# 给客户端响应消息new_socket.send(response)finally:# 关闭链接new_socket.close()class HttpWebServer():def __init__(self):# ipv4 地址  tcp链接tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 端口号复用tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)# 设置端口号tcp_server_socket.bind(('',8000))# 设置监听tcp_server_socket.listen(128)# 把tcp服务器作为web服务器使用self.tcp_server_socket = tcp_server_socket# 启动服务器的方法def start(self):while True:new_socket,ip_port = self.tcp_server_socket.accept()sub_thread = threading.Thread(target=handle_client_request,args=(new_socket,))sub_thread.setDaemon(True)sub_thread.start()def main():web_server = HttpWebServer()web_server.start()if __name__ == '__main__':main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/32005.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

04_FFmpeg常用API及内存模型

【说明】课程学习地址:https://ke.qq.com/course/468797 FFmpeg内存模型 FFmpeg内存模型 int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt); int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);问题(数据的申请和释放): …

1.1 数据采集总览

正所谓巧妇难为无米之炊,数据采集是数据处理的第一步。 什么是数据采集 数据采集,也称为数据收集,是将原始数据从各种来源获取并存储起来的过程。这个过程是数据分析和数据仓库建设的第一步,涉及到从不同的数据源中提取数据&…

Spring的自动注入(也称为自动装配)

自动注入(也称为自动装配)是Spring框架中的一个核心概念,它与手动装配相对立,提供了一种更简洁、更灵活的方式来管理Bean之间的依赖关系。 在Spring应用程序中,如果类A依赖于类B,通常需要在类A中定义一个类…

如何设置数据库的隔离级别

1、MySQL 1、设置会话级别的隔离级别: SET SESSION TRANSACTION ISOLATION LEVEL <隔离级别>;其中&#xff0c;<隔离级别> 可以是以下之一&#xff1a; READ UNCOMMITTED READ COMMITTED REPEATABLE READ SERIALIZABLE2、设置全局级别的隔离级别: SET GLOBAL T…

qt 一个可以拖拽的矩形

1.概要 2.代码 2.1 mycotrl.h #ifndef MYCOTRL_H #define MYCOTRL_H#include <QWidget> #include <QMouseEvent>class MyCotrl: public QWidget {Q_OBJECT public://MyCotrl();MyCotrl(QWidget *parent nullptr); protected:void paintEvent(QPaintEvent *even…

MySQL 死锁查询和解决死锁

来了来了来了&#xff01;客户现场又要骂街了&#xff0c;你们这是什么破系统怎么这么慢啊&#xff1f;&#xff01;&#xff1f;&#xff01; 今天遇到了mysql死锁&#xff0c;直接导致服务器CPU被PUA直接GUA了&#xff01; 别的先别管&#xff0c;先看哪里死锁&#xff0c;或…

【MySQL数据库】:MySQL视图特性

视图的概念 视图是一个虚拟表&#xff0c;其内容由查询定义&#xff0c;同真实的表一样&#xff0c;视图包含一系列带有名称的列和行数据。视图中的数据并不会单独存储在数据库中&#xff0c;其数据来自定义视图时查询所引用的表&#xff08;基表&#xff09;&#xff0c;在每…

[保姆级教程]uniapp实现底部导航栏

文章目录 前置准备工作安装HBuilder-X新建uniapp项目教程使用HBuilder-X启动uniapp项目教程 实现底部导航栏package.json中配置导航栏详细配置内容 前置准备工作 安装HBuilder-X 详细步骤可看上文》》 新建uniapp项目教程 详细步骤可看上文》》 使用HBuilder-X启动uniapp项…

在 Vue 3 中设置 `@` 指向根目录的方法汇总

在 Vue 3 项目开发中&#xff0c;为了方便管理和引用文件路径&#xff0c;设置 指向根目录是一项常见的需求。以下为您总结了几种常见的实现方式。 方法一&#xff1a;使用 Vite 配置&#xff08;适用于 Vite 构建的项目&#xff09; 在项目根目录创建 vite.config.js 文件&a…

Python里的UNicode是什么类型?

在Python中&#xff0c;Unicode&#xff08;统一码&#xff09;不是一个特定的数据类型&#xff0c;而是一种编码标准&#xff0c;用于表示世界上大多数书写系统中的字符&#xff08;包括字母、数字、标点符号等&#xff09;。然而&#xff0c;Python提供了几种数据类型来存储和…

计组复习题整理

第三章 &#xff08;1&#xff09;直接映射 cache 的主要优点是实现简单。这种方式的主要缺点是&#xff08; &#xff09; A、它比其他 cache 映射方式价格更贵 B、如果使用中的 2 个或多个块映射到 cache 同一行&#xff0c;命中率则下降 C、它的存取时间大于其它 cache …

vivado、vitis2022安装及其注意事项(省时、省空间)

1、下载 AMD官网-资源与支持-vivado ML开发者工具&#xff0c;或者vitis平台&#xff0c; 下载的时候有个官网推荐web安装&#xff0c;亲测这个耗时非常久&#xff0c;不建议使用&#xff0c;还是直接下载89G的安装包快。 注意&#xff1a;安装vitis平台会默认安装vivado&…

【Deep Learning】Self-Supervised Learning:自监督学习

自监督学习 本文基于清华大学《深度学习》第12节《Beyond Supervised Learning》的内容撰写&#xff0c;既是课堂笔记&#xff0c;亦是作者的一些理解。 在深度学习领域&#xff0c;传统的监督学习(Supervised Learning)的形式是给你输入 x x x和标签 y y y&#xff0c;你需要训…

SpringBoot开发使用@ConfigurationProperties代替@Value笔记

一、背景 最近在项目开发中&#xff0c;遇到大量配置信息在不同微服务中使用&#xff0c;发现维护配置信息变得越来越复杂&#xff0c;修改一个配置命名&#xff0c;就要连着改好多Value&#xff0c;因为配置管理而头疼。 二、Value注解 可以轻松地将配置文件中的值注入到Sp…

GSettings(五)——没有图形界面的环境,调用gsettings

“没有图形界面的环境”是指没有运行桌面环境或窗口管理器的情况下运行程序。也就是说&#xff0c;可能是在一个纯命令行界面或服务器环境中工作&#xff0c;没有访问显示服务器&#xff08;如X11或Wayland&#xff09;的情况。 情景解释 没有图形界面的环境 这种情况下&#…

Odoo专题资料

odoo开发规范 | 同欣数字化落地 (txodoo.cn) odoo性能优化思路 | 同欣数字化落地 (txodoo.cn) 生产环境安装odoo | 同欣数字化落地 (txodoo.cn) odoo开发环境搭建windows版详细教程 | 同欣数字化落地 (txodoo.cn) mac安装odoo17 | 同欣数字化落地 (txodoo.cn) 控制表单默认…

贪心算法练习题(2024/6/21)

1 买卖股票的最佳时机 II 给你一个整数数组 prices &#xff0c;其中 prices[i] 表示某支股票第 i 天的价格。 在每一天&#xff0c;你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买&#xff0c;然后在 同一天 出售。 返回 你能获得…

论文学习_Fuzz4All: Universal Fuzzing with Large Language Models

论文名称发表时间发表期刊期刊等级研究单位Fuzz4All: Universal Fuzzing with Large Language Models2024年arXiv-伊利诺伊大学0.摘要 研究背景模糊测试再发现各种软件系统中的错误和漏洞方面取得了巨大的成功。以编程或形式语言作为输入的被测系统(SUT),例如编译器、运行时…

树莓派4B_OpenCv学习笔记12:OpenCv颜色追踪_画出轨迹

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1&#xff1a; 今日尝试使用倒叙的方式来学习OpenCV颜色追踪&#xff0…

Claude 3.5 强势出击:解析最新AI模型的突破与应用

近年来&#xff0c;人工智能领域的发展迅猛&#xff0c;各大科技公司纷纷推出了自家的高级语言模型。在这场技术竞赛中&#xff0c;Anthropic的Claude系列模型凭借其强大的性能和创新的功能脱颖而出。最近&#xff0c;Anthropic发布了Claude 3.5 Sonnet模型&#xff0c;引起了广…