HTTPserver v3.0 版本项目
项目介绍
模拟使用 socket 多线程 / io多路复用 实现一个简单的 httpserver 和 webframe 交互的项目程序
期望可以实现简单的 以 http 协议为标准的 和浏览器 / 前端框架的 数据交互
以及 实现简单的 前端框架模型
项目需求分析
项目分为两部分 httpserver 部分以及 webframe 部分
HTTPserver 部分
1. 获取 http 请求
2. 解析 http 请求
3. 将请求发送给 WebFrame
4. 从 WebFrame 接收数据信息
5. 将数据信息组织为 Response 发送给客户端
WebFrame 部分
1. 从 httpserver 获取具体请求
2. 根据请求进行逻辑或者数据处理 (简单处理, 这里不会过分细致)
3. 将数据资源发送给 httpserver
两部分整合后应实现的程度
1. httpserver 与应用程序分离, 各自独立
2. 独立开发, 降低互相干扰, 采用各自的配置模式
3. 在后端应用程序中优化数据的处理模型 (暂时就先不做了)
高并发需求处理
1. 多线程
2. IO 多路复用
项目实现
项目结构


项目流程

项目源码
httpserver 部分
httpserver.py
内部实现功能
1. 作为浏览器的 socket_server 需要创建------>服务器套接字 (配合多线程)
2. 接收浏览器的 请求进行处理 ------> 处理函数
3. 作为 webframe 的 socket_client 需要创建------->客户端套接字
4. 向 webframe 发送请求 -------> 处理函数
#!/user/bin/env python3
# coding=utf8
"""
AID httpserver v3.0
""" from socket import *
import sys
import json
from threading import Thread # 导入配置信息
from httpserver_config import * # 向 frame 发送请求
def connect_frame(**kwargs):
s = socket()
try:
s.connect(frame_address)
except Exception as e:
print(e)
return
# 将请求发送给 frame
s.send(json.dumps(kwargs).encode())
data = s.recv(4096).decode()
return data # 封装 httpserver 基本功能
class HTTPserver(object):
def __init__(self, address):
self.address = address
self.create_socket()
self.bind(address) # 创建套接字
def create_socket(self):
self.sockfd = socket()
self.sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, DEBUG) # 绑定监听地址和端口
def bind(self, address):
self.ip = address[0]
self.port = address[1]
self.sockfd.bind(address) # 启动服务
def serve_forever(self):
self.sockfd.listen(10)
print("Listen the port %d ..." % self.port)
while True:
try:
connfd, addr = self.sockfd.accept()
print("Connect from", addr)
except KeyboardInterrupt:
self.sockfd.close()
sys.exit("退出 httpserver 服务")
except Exception as e:
print(e)
continue
client = Thread(target=self.handle, args=(connfd,))
client.setDaemon(True)
client.start() # 处理浏览器的 http 请求
def handle(self, connfd):
request = connfd.recv(4096)
# 处理客户端断开
if not request:
connfd.close()
return
request_lines = request.splitlines()
# 获取请求行
request_lines = request_lines[0].decode("utf-8")
print(request_lines)
# 这里可以使用正则当然更好, 但是目前来说无大用
# 获取请求方法, 请求内容
tmp = request_lines.split(" ")
method = tmp[0]
path_info = tmp[1] data = connect_frame(method=method, path_info=path_info) self.response(connfd, data) # 处理返回的数据内容
def response(self, connfd, data): # 根据情况组织响应
if data != "":
response_headlers = "HTTP/1.1 200 OK\r\n"
else:
response_headlers = "HTTP/1.1 404 Not Found\r\n" response_headlers += '\r\n'
response_body = data
response = response_headlers + response_body
connfd.send(response.encode())
connfd.close() httpd = HTTPserver(ADDR)
httpd.serve_forever() # 启动服务程序
httpserver_config.py
htttpserver 的配置文件相关
"""
HTTPserver 配置文件, 用户填写基本的必要信息
""" # HTTPserver
HOST = "0.0.0.0"
PORT = 8000
ADDR = (HOST, PORT) # debug 设置为 True 表示调试
DEBUG = True # 配合 WebFrame 地址
frame_ip = "127.0.0.1"
frame_port = 8080
frame_address = (frame_ip, frame_port)
webframe 部分
webframe.py
内部实现功能
1. 作为 httpserver 的服务端处理其请求 ----> 创建 socket_server ( IO多路复用 select 方式 )
2. 处理请求 ----> 对具体的 url 具体分支处理函数
#!/user/bin/env python3
# coding=utf8 """
模拟网站后端应用处理程序
httpserver v3.0
""" from socket import *
import select
import json # 导入配置文件
from settings import *
from views import * # 创建应用类, 用于具体处理请求
class Application(object):
def __init__(self):
self.ip = frame_address[0]
self.port = frame_address[1]
self.sockfd = socket()
self.sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
self.sockfd.bind(frame_address) def start(self):
self.sockfd.listen(5)
print("Listen the port %d" % self.port)
rlist = [self.sockfd]
wlist = []
xlist = []
while True:
rs, ws, xs = select.select(rlist, wlist, xlist)
# 循环检查是否就绪
for r in rs:
# 判断加入 关注列表
if r is self.sockfd:
connfd, addr = r.accept()
rlist.append(connfd)
else:
# 接受 httpserver 的请求
request = r.recv(2048).decode()
if not request:
rlist.remove(r)
continue
self.handle(r, request) # 处理请求
def handle(self, connfd, request):
request = json.loads(request)
method = request["method"]
path_info = request["path_info"]
print(path_info)
if method == "GET":
if path_info == "/" or path_info[-5:] == ".html":
data = self.get_html(path_info)
else:
data = self.get_data(path_info)
elif method == "POST":
pass
# 得到网页内容就发送 未得到就发送404
if data:
connfd.send(data.encode())
else:
connfd.send(b"") # 处理网页
def get_html(self, path_info):
if path_info == "/":
get_file = STATIC_DIR + "/index.html"
else:
get_file = STATIC_DIR + path_info
try:
fd = open(get_file, encoding="utf8")
data = fd.read()
except IOError:
return
return data # 处理数据
def get_data(self, path_info):
for url, func in urls:
if path_info == url:
return func()
return "" app = Application()
app.start() # 启动后端框架服务
settings.py
框架的配置文件
以及 自定义的函数对应方法的映射配置 类似于 Django 的路由系统
"""
Frame 程序配置文件
"""
from views import * # 配置框架地址
frame_ip = "0.0.0.0"
frame_port = 8080
frame_address = (frame_ip, frame_port) # 静态网页位置
STATIC_DIR = "./static" #
urls = [
("/time", show_time),
("/hello", say_hello)
]
views.py
自定义的返回视图函数, 类似于 Django 的 视图系统
import time def show_time():
return time.ctime() def say_hello():
return "Hello world"
HTTPserver v3.0 版本项目的更多相关文章
- RDIFramework.NET ━ .NET快速信息化系统开发框架钜献 V3.0 版本强势发布
继上个版本“RDIFramework.NET V2.9版本”的推出,受到了重多客户的认可与选择,V2.9版本是非常成功与稳定的版本,感谢大家的认可与长期以来的关注与支持.V3.0版本在V2.9版本的基 ...
- RDIFramework.NET平台代码生成器V3.0版本全新发布-更新于20160518(提供下载)
最新版本请转到:RDIFramework.NET平台代码生成器V3.1版本全新发布-更新于2016-10-08(提供下载) RDIFramework.NET代码生成器V3.0版本修改了针对3.0版本的 ...
- RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.0 版本新增序列管理
欲了解V3.0版本的相关内容可查看下面的链接地址. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.0 版本发布 在V3.0版本的Web(Mvc.WebForm)与WinF ...
- vue-cli脚手架——3.0版本项目案例
一.[准备工作] node与git部分见vue-cli2.0搭建案例 vue-cli3.0是一个基于 Vue.js 进行快速开发的完整系统.有三个组件: CLI:@vue/cli 全局安装的 npm ...
- vue-cli脚手架——2.0版本项目案例
一.[准备工作] Node.js 安装包及源码下载地址为:https://nodejs.org/en/download/. Git 各平台安装包下载地址为:http://git-scm.com/dow ...
- (分享)多功能 PDF转换器v3.0版本
转换的效果非常不错,值得使用.破解成功的截图:这个程序必须随便输入注册码注册,不然会有水印的. 这是程序主界面了 正在测试pdf转word过程,转换结果个人感觉非常不错,跟原版pdf的格式非常接近,个 ...
- 采石厂管理系统V3.0版本上线(采石厂车辆出入管理系统,石厂开票系统)
新版系统包含老版所有功能,软件基础功能请点击查看<采石管理系统,采石厂车辆出入管理系统> 新增功能点 近期对采石厂管理系统进行了升级和完善,系统更加灵活好用,应用场景更加广泛.主要更新一下 ...
- Cocos2dx-3.0版本 从开发环境搭建(Win32)到项目移植Android平台过程详解
作为重量级的跨平台开发的游戏引擎,Cocos2d-x在现今的手游开发领域占有重要地位.那么问题来了,作为Cocos2dx的学习者,它的可移植特性我们就需要掌握,要不然总觉得少一门技能.然而这个时候各种 ...
- RDIFramework.NET平台代码生成器V3.1版本全新发布-更新于2016-10-29(提供下载)
本次主要更新内容: 1.增加对Oracle表创建语句的查看. 2.新增对MySql的代码生成支持. 3.全面重构对多线程的支持,改变以前会无故退出的现象. RDIFramework.NET代码生成器V ...
随机推荐
- Mysql启动找不到mysql.sock文件问题(Centos7)
刚装完Mysql5.7,将Mysql添加到开机自启.reboot之后mysql服务却没启动起来, 直接输入mysql –uroot –p ,出现如下错误,找不到mysql.sock文件.用servic ...
- Contest1692 - 2019寒假集训第三十一场 UPC 11075 Problem D 小P的国际象棋
非常简单的单点修改+区间加+区间查询.我用的是最近刚学的区间修改版本树状数组. 直接维护即可,注意修改后的单点值已经不是a[i],或者b[i],要通过区间查询求单点.不然是错的. 区间修改版本树状数 ...
- Python—反射
反射 1 什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它 ...
- 对Vuejs框架原理名词解读
渐进式()+虚拟Dom: vue-cli 遍历Dom:先序遍历DOM树的5种方法! 三层架构+m v c +mvp+m v vm()+MVC,MVP 和 MVVM 的图示 剖析vue MVVM实现原理 ...
- poj3984 广度搜索BFS
迷宫问题 Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1 ...
- (第十三周)评论Final发布II
按课上展示的顺序对每组进行点评:(性能.功能.UI.部署) 1. Nice! 项目:约跑软件 软件操作的响应很快,俩人进行聊天时可以实现消息的及时传递.功能主要有:注册账号.登录.创建/删除跑步计划 ...
- PS滤镜给城市夜空照片添加满天星
原图 一.新建空白图层. 二.填充黑色(编辑→填充). 三.转换为智能对象. 四.添加杂色(滤镜→杂色→添加杂色). 五.使用高斯模糊(滤镜→模糊→高斯模糊). 六.如果你想再次修改模糊效果,可双击该 ...
- c++局部变量在外可用的方法
C++的局部变量在作用域结束后,一般都会被回收.如下面这段代码 map<a*, b*> _map; void fun() { a _a; b _b; _map[&_a] = &am ...
- 一些Cassandra+YCSB异常
这两天一直在用YCSB.昨天还可以用的YCSB,今天在测试Cassandra时遇到问题了. 环境是在公用局域网的一台debian机器,YCSB和Cassandra都在这台机器上.异常是开始运行YCSB ...
- Python之参数类型、变量
一.参数类型 (一)形参与实参 要使用局部变量时,只能通过return的方式返回 def my(name): #函数体 return name my('lrx') #name是形参,lrx是实参 不写 ...