Python使用socket实现简易的http服务
在接触的一些项目中,有时为了方便可视化一些服务状态(请求数很少),那么很容易想到使用http服务来实现。但开源的web后端框架,例如flask,fastapi,django等略显沉重,且使用这些框架会有各种各样的限制,为了更加灵活的使用,可以自己通过Python自带的socket库来实现,下面是我简单实现的代码,贴在这里方便后续使用。
客户端代码:
import os
import time
import json
import socket
import datetime
import traceback
from urllib import parse
from concurrent.futures import ThreadPoolExecutorENCODING = "utf-8"class CustomRouter:def __init__(self):self.router_dict = {}def register(self, url: str, method: str):if method not in ["GET", "POST"]:raise ValueError(f"method only support GET or POST, got {method}")key = f"{url}:{method}"if key in self.router_dict:raise ValueError(f"url:{url} method:{method} already registed")def _register(func):self.router_dict[key] = funcreturn funcreturn _registerdef has_register(self, url: str, method: str):key = f"{url}:{method}"return key in self.router_dictdef request(self, url: str, method: str):key = f"{url}:{method}"func = self.router_dict[key]return func()router = CustomRouter()@router.register(url="/", method="GET")
def task():return "Hello World!!!"@router.register(url="/get_project_info", method="GET")
def get_project_info():info = {"pwd": os.path.abspath(os.curdir),"encoding": ENCODING,"time": datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}return json.dumps(info)class CustomServer:def __init__(self, port: int = 5055, backlog: int = 2, num_workers: int = 2):self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)self.server.bind(("", port))self.server.listen(backlog)self.buff_size = 1024self.encoding = ENCODINGself.router = routerself.timeout = 60self.thread_pool = ThreadPoolExecutor(max_workers=num_workers)def parse_message(self, message: str):method, url_params, message = message.split(" ", maxsplit=2)res = parse.urlparse(url_params)url = res.pathparams = dict([i for i in parse.parse_qsl(res.query)])version, message = message.split("\r\n", maxsplit=1)return method, url, params, versiondef task(self, conn: socket.socket, addr):conn.settimeout(self.timeout)try:message = conn.recv(self.buff_size).decode(self.encoding)t0 = time.perf_counter()method, url, params, version = self.parse_message(message)if not self.router.has_register(url, method):conn.send("HTTP/1.1 501 Not Implemented\r\n\r\n".encode(self.encoding))print(f"[{method}][501]client addr: {addr} request: {url}, time: {time.perf_counter() - t0:.5f}")conn.close()returnres = self.router.request(url, method)conn.send("HTTP/1.1 200 OK\r\n\r\n".encode(self.encoding))conn.send(res.encode(self.encoding))print(f"[{method}][200]client addr: {addr} request: {url}, time: {time.perf_counter() - t0:.5f}")except (BrokenPipeError, TimeoutError):print(traceback.format_exc())except:print(traceback.format_exc())conn.send("HTTP/1.1 500 Inner Error\r\n\r\n".encode(self.encoding))print(f"[{method}][500]client addr: {addr} request: {url}, time: {time.perf_counter() - t0:.5f}")finally:conn.close()def run(self):while True:conn, addr = self.server.accept()self.thread_pool.submit(self.task, conn, addr)if __name__ == '__main__':s = CustomServer()s.run()
客户端代码:
import requestsdef main():for _ in range(50):res = requests.get("http://127.0.0.1:5055")print(res.status_code, res.text)res = requests.get("http://127.0.0.1:5055/get_project_info")print(res.status_code, res.json())if __name__ == '__main__':main()
客户端请求时,服务端终端输出:
[GET][200]client addr: ('127.0.0.1', 38054) request: /, time: 0.00002
[GET][200]client addr: ('127.0.0.1', 38058) request: /get_project_info, time: 0.00004
[GET][200]client addr: ('127.0.0.1', 38060) request: /, time: 0.00002
[GET][200]client addr: ('127.0.0.1', 38070) request: /get_project_info, time: 0.00004
[GET][200]client addr: ('127.0.0.1', 38080) request: /, time: 0.00002
[GET][200]client addr: ('127.0.0.1', 38096) request: /get_project_info, time: 0.00004
[GET][200]client addr: ('127.0.0.1', 38098) request: /, time: 0.00002
[GET][200]client addr: ('127.0.0.1', 38114) request: /get_project_info, time: 0.00009
[GET][200]client addr: ('127.0.0.1', 38120) request: /, time: 0.00003
[GET][200]client addr: ('127.0.0.1', 38122) request: /get_project_info, time: 0.00006
[GET][200]client addr: ('127.0.0.1', 38136) request: /, time: 0.00003
[GET][200]client addr: ('127.0.0.1', 38146) request: /get_project_info, time: 0.00006
[GET][200]client addr: ('127.0.0.1', 38160) request: /, time: 0.00003
[GET][200]client addr: ('127.0.0.1', 38172) request: /get_project_info, time: 0.00005
[GET][200]client addr: ('127.0.0.1', 38178) request: /, time: 0.00002
[GET][200]client addr: ('127.0.0.1', 38182) request: /get_project_info, time: 0.00005
客户端终端输出:
200 Hello World!!!
200 {'pwd': '/home/wz/my_projects/others/socket_t', 'encoding': 'utf-8', 'time': '2025-01-14 00:20:01'}
200 Hello World!!!
200 {'pwd': '/home/wz/my_projects/others/socket_t', 'encoding': 'utf-8', 'time': '2025-01-14 00:20:01'}
200 Hello World!!!
200 {'pwd': '/home/wz/my_projects/others/socket_t', 'encoding': 'utf-8', 'time': '2025-01-14 00:20:01'}
200 Hello World!!!
200 {'pwd': '/home/wz/my_projects/others/socket_t', 'encoding': 'utf-8', 'time': '2025-01-14 00:20:01'}
200 Hello World!!!
200 {'pwd': '/home/wz/my_projects/others/socket_t', 'encoding': 'utf-8', 'time': '2025-01-14 00:20:01'}
200 Hello World!!!
200 {'pwd': '/home/wz/my_projects/others/socket_t', 'encoding': 'utf-8', 'time': '2025-01-14 00:20:01'}
200 Hello World!!!
200 {'pwd': '/home/wz/my_projects/others/socket_t', 'encoding': 'utf-8', 'time': '2025-01-14 00:20:01'}
200 Hello World!!!
200 {'pwd': '/home/wz/my_projects/others/socket_t', 'encoding': 'utf-8', 'time': '2025-01-14 00:20:01'}
相关文章:
Python使用socket实现简易的http服务
在接触的一些项目中,有时为了方便可视化一些服务状态(请求数很少),那么很容易想到使用http服务来实现。但开源的web后端框架,例如flask,fastapi,django等略显沉重,且使用这些框架会有…...
【Hive】海量数据存储利器之Hive库原理初探
文章目录 一、背景二、数据仓库2.1 数据仓库概念2.2 数据仓库分层架构2.2.1 数仓分层思想和标准2.2.2 阿里巴巴数仓3层架构2.2.3 ETL和ELT2.2.4 为什么要分层 2.3 数据仓库特征2.3.1 面向主题性2.3.2 集成性2.3.3 非易失性2.3.4 时变性 三、hive库3.1 hive概述3.2 hive架构3.2.…...
linux系统监视(centos 7)
一.系统监视 1.安装iostat,sar,sysstat(默认没有,安装过可以跳跃) iostat 和 sar: 同样,iostat 和 sar 是 sysstat 软件包的一部分。使用以下命令安装:sudo yum install sysstat解释…...
Blazor中Syncfusion图像编辑器组件使用方法
Blazor中Syncfusion图像编辑器组件是一个功能丰富的图像处理工具,支持多种编辑、操作和交互方式,帮助用户高效处理图像。以下是该组件的主要功能总结: 主要功能: 图像打开与保存 图像编辑器允许用户通过简单的点击操作打开支持的…...
电动汽车V2G技术Matlab/Simulink仿真模型
今天给大家更新关于V2G技术的仿真,不是研究这个方向的,可能会对这个名称比较陌生,那么,什么是“V2G”? V2G全称:Vehicle-to-Grid,即车网互动,利用电动汽车特有的储能功能与电网“双…...
C++中的unordered_set和unordered_map的模拟实现
一、封装基本结构 与map和set的封装过程很想,unordered_set和unordered_map也需要用MapKeyOfT和SetKeyOfT创建哈希表类型,借此获取对应的key值来使用; 因此,在哈希表中也一样需要用参数class T来替代set中的key和map中的pair<…...
Spring Boot 2 学习指南与资料分享
Spring Boot 2 学习资料 Spring Boot 2 学习资料 Spring Boot 2 学习资料 在当今竞争激烈的 Java 后端开发领域,Spring Boot 2 凭借其卓越的特性,为开发者们开辟了一条高效、便捷的开发之路。如果你渴望深入学习 Spring Boot 2,以下这份精心…...
(一)QSQLite3库简介
1、SQLite数据库 SQLite数据库,作为一个轻量级的关系型数据库管理系统,广泛应用于移动设备和桌面应用程序中。由于其简单易用、无需配置的特点,它为开发者提供了极大的便利。然而,正是由于其应用广泛,随着用户对于系统…...
《计算机网络》课后探研题书面报告_网际校验和算法
网际校验和算法 摘 要 本文旨在研究和实现网际校验和(Internet Checksum)算法。通过阅读《RFC 1071》文档理解该算法的工作原理,并使用编程语言实现网际校验和的计算过程。本项目将对不同类型的网络报文(包括ICMP、TCP、UDP等&a…...
hot100_240. 搜索二维矩阵 II
hot100_240. 搜索二维矩阵 II 直接遍历列减行增 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 示例 1: 输入:matrix [[1,4,7,1…...
78_Redis网络模型
1.Redis网络模型概述 1.1 Redis网络模型介绍 Redis 7.x的网络模型基于epoll的Reactor模式实现,这是一个高效的事件驱动模型。在Redis中,所有的网络事件(如连接、读写等)都由一个事件循环(Event Loop)来处理。这个事件循环负责监听套接字上的事件,并根据事件类型调用相…...
python范围
用户图形界面-工资计算器 from tkinter import *def f():w int(e1.get()) int(e2.get()) - int(e3.get())wage.insert(0,w)root Tk() root.title("工资计算器") Label(root, text"每月基本工资:").pack() e1 Entry(root) e1.pack() Label(…...
vulnhub靶场【Raven系列】之2 ,对于mysql udf提权的复习
前言 靶机:Raven-2,IP地址为192.168.10.9 攻击:kali,IP地址为192.168.10.2 都采用虚拟机,网卡为桥接模式 文章所用靶机来自vulnhub,可通过官网下载,或者通过链接:https://pan.quark.cn/s/a65…...
基于vite+vue3+mapbox-gl从零搭建一个项目
下面是基于 Vite、Vue 3 和 Mapbox GL 从零搭建一个项目的完整步骤,包括环境搭建、依赖安装、配置和代码示例。 1. 初始化项目 首先,使用 Vite 快速创建一个 Vue 3 项目: npm create vuelatest vue3-mapboxgl --template vue cd vue3-mapbo…...
向harbor中上传镜像(向harbor上传image)
向 Harbor 中上传镜像通常分为以下几个步骤: 1、登录 Harbor 2、构建镜像 3、标记镜像 4、推送镜像到 Harbor 仓库 1、登录 Harbor 首先,确保你已经能够访问 Harbor,并且已经注册了账户。如果还没有 Harbor 账户,你需要先注册一…...
【线性代数】行列式的性质
行列式性质定理讲义 一、行列式的基本性质 性质 1:行列互换 对于任意一个 n n n \times n nn 的方阵 A A A,其行列式 ∣ A ∣ |A| ∣A∣ 满足: ∣ A ∣ ∣ A T ∣ |A| |A^T| ∣A∣∣AT∣ 其中, A T A^T AT 是 A A A 的…...
智能家居企业如何通过设计师渠道打造第二曲线?
随着智能家居行业的迅速发展和消费者需求的不断升级,企业的营销策略也在不断变化。传统的B2C营销模式逐渐让位于更加精细化、定制化的B2B2C模式,其中设计师渠道的开发与合作,成为智能家居企业布局市场、提升品牌影响力的关键。 智能家居推广的…...
Unity3d 实时天气系统基于UniStorm插件和xx天气API实现(含源码)
前言 实时天气在Unity3d三维数字沙盘中的作用非常重要,它能够增强虚拟环境的真实感和互动性,实时天气数据的应用可以提供更为精准和直观的天气信息支持,如果真实的数据加上特效、声音和模型反馈会提高产品档次,提高真实感。 目前…...
年后找工作需要注意的事项
大家好!我是 [数擎 AI],一位热爱探索新技术的前端开发者,在这里分享前端和 Web3D、AI 技术的干货与实战经验。如果你对技术有热情,欢迎关注我的文章,我们一起成长、进步! 开发领域:前端开发 | A…...
模拟器多开窗口单IP与代理IP关系
模拟器多开窗口同IP背后出现的问题 在游戏世界中,模拟器多开窗口是玩家们提升体验的常见做法。通过在同一设备上开启多个模拟器窗口,玩家可以同时运营多个游戏账号,增加游戏的趣味性和效率。 一旦检测到一个IP地址下登录了过多的账号&#x…...
用Multisim 14.0和AD620/OP07,手把手教你搭建一个能用的简易心电放大电路
从零开始构建心电放大电路:Multisim 14.0与AD620/OP07实战指南 在生物医学信号处理领域,心电信号采集一直是极具挑战性的课题。想象一下,当医生将电极贴在你胸口时,那些微弱的电信号是如何被放大并转化为清晰波形图的?…...
雪女-斗罗大陆-造相Z-Turbo实战:卷积神经网络(CNN)特征与生成图像的风格融合
雪女-斗罗大陆-造相Z-Turbo实战:卷积神经网络(CNN)特征与生成图像的风格融合 最近在玩一个挺有意思的东西,就是把现实世界照片里的“感觉”提取出来,然后让AI照着这个“感觉”去画一张斗罗大陆风格的画。听起来有点玄…...
零门槛视频创作:OpenCut高效替代方案全解析
零门槛视频创作:OpenCut高效替代方案全解析 【免费下载链接】OpenCut The open-source CapCut alternative 项目地址: https://gitcode.com/gh_mirrors/ap/OpenCut 在数字内容创作爆炸的时代,视频编辑工具的选择直接影响创作效率与作品质量。Open…...
文墨共鸣企业内训系统搭建:基于AI的个性化学习路径与技能评估
文墨共鸣企业内训系统搭建:基于AI的个性化学习路径与技能评估 最近和几个做企业培训的朋友聊天,大家普遍头疼一个问题:公司花大价钱采购的在线学习平台,员工不爱用。要么是课程千篇一律,老员工觉得没意思;…...
别再手动传文件了!用MinIO Java SDK的预签名URL功能,5分钟搞定安全文件分享
别再手动传文件了!用MinIO Java SDK的预签名URL功能,5分钟搞定安全文件分享 上周团队新来的架构师老张给我看了一个令人后怕的日志:某个内部系统的文件下载接口在24小时内被调用了17万次,而实际业务需求只有不到200次。调查发现是…...
不止于画图:用@antv/g6-editor的Command系统打造可撤销/重做的智能流程设计器
超越基础绘图:利用antv/g6-editor构建企业级智能流程设计器 在当今快速发展的数字化时代,流程设计工具已成为企业数字化转型的核心组件。从简单的审批流程到复杂的业务编排,一个功能完备的流程设计器不仅能提升工作效率,更能确保…...
Alt App Installer革新:突破微软商店限制的Windows应用安装解决方案
Alt App Installer革新:突破微软商店限制的Windows应用安装解决方案 【免费下载链接】alt-app-installer A Program To Download And Install Microsoft Store Apps Without Store 项目地址: https://gitcode.com/gh_mirrors/alt/alt-app-installer 微软商店…...
保姆级教程:用迪文屏官方工具生成30x30点阵汉字库,搞定界面文本显示
嵌入式UI开发实战:迪文屏3030点阵汉字库生成全流程指南 在嵌入式设备的人机交互界面开发中,文本显示是最基础却最容易出问题的环节之一。许多开发者第一次使用迪文屏时,往往会被字库生成工具的参数设置难住——为什么明明生成了字库…...
YOLOv12:以注意力机制重塑实时目标检测的精度与速度边界
1. YOLOv12如何重新定义实时目标检测 当你在手机上刷短视频时,那些自动标记出人物、宠物和物品的方框;当你在超市自助结账时,摄像头快速识别商品的过程;当自动驾驶汽车实时判断前方路况时——这些场景背后都有一个共同的技术支撑&…...
使用Python运行VirtualLab Fusion光学仿真
摘要 VirtualLab Fusion允许Python外部访问其建模技术、求解器和结果。这个用例介绍了一种使用路径变量和Visual Studio代码将Python连接到VirtualLab Fusion的简单方法。在本示例中,我们将演示如何使用Python脚本运行光学仿真,以向用户简要概述这种跨…...
