python-实现动态web服务器


#
encoding=utf-8 import socket from multiprocessing import Process import re import sys# 设置静态文件根目录 HTML_ROOT_DIR = './html'WSGI_PYTHON_DIR = './wsgipython'class HTTPServer(object):def __init__(self, application):self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)self.app = applicationdef start(self):self.server_socket.listen(128)while True:client_socket, client_address = self.server_socket.accept()# print("[%s, %s]用户连接上了" % (client_address[0], client_address[1]))print("[%s, %s]用户连接上了" % client_address)handle_client_process = Process(target=self.handle_socket, args=(client_socket,))handle_client_process.start()client_socket.close()def start_response(self, status, headers):"""status="200 ok"headers = [('Content-Type', 'text/plain')]:param status::param headers::return:"""response_headers = "HTTP1.1 " + status + "\r\n"for header in headers:response_headers += "%s: %s\r\n" % headerself.response_headers = response_headersdef handle_socket(self, client_socket):"""处理客户端请求"""# 获取客户端请求数据request_data = client_socket.recv(1024)print("request data: ", request_data)request_lines = request_data.splitlines()for request_line in request_lines:print(request_line)# 解析请求报文# 'GET / HTTP/1.1'request_start_line = request_lines[0]print('&' * 20)print(type(request_start_line))# 提取用户请求的文件名print('*' * 10)print(request_start_line.decode('utf-8'))file_name = re.match(r"\w+ +(/[^ ]*) ", request_start_line.decode('utf-8')).group(1)method = re.match(r"(\w+) +/[^ ]* ", request_start_line.decode('utf-8')).group(1)print(file_name)
# 将路由的分发交给框架去做 ====================================================
# # "/ctime.py"# # "/sayhello.py"# if file_name.endswith('.py'):# a = file_name[1:-3]# try:# m = __import__(file_name[1:-3])# except Exception:# self.response_headers = "HTTP/1/1 404 Not Found\r\n"# response_body = 'not found'# else:# env = {# "PATH_INFO": file_name,# 'METHOD': method# }# # response_body = m.application(env, self.start_response)# # response = self.response_headers + '\r\n' + response_body# # else:# if '/' == file_name:# file_name = '/index.html'# # # 打开文件,读取内容# try:# file = open(HTML_ROOT_DIR + file_name, "rb")# except IOError:# response_start_line = 'HTTP/1.1 404 Not Found\r\n'# response_headers = 'Server: Myserver\r\n'# response_body = 'The file is not found!'# else:# file_data = file.read()# file.close()# # #  构造响应数据# response_start_line = 'HTTP/1.1 200 OK\r\n'# response_headers = 'Server: Myserver\r\n'# response_body = file_data.decode('utf-8')# print('??' * 20)# print(type(response_body))# # response = response_start_line + response_headers + '\r\n' + response_body# print('response data:', response) env = {"PATH_INFO": file_name,'METHOD': method}response_body = self.app(env, self.start_response)response = self.response_headers + '\r\n' + response_body# 向客户端返回响应数据client_socket.send(bytes(response, 'utf-8'))# 关闭客户端连接 client_socket.close()def bind(self, port):self.server_socket.bind(("", port))def main():sys.path.insert(1, WSGI_PYTHON_DIR)if len(sys.argv) < 2:sys.exit("python MyWebServer_v1.py Module:app")# python MyWebServer_v1.py MyWebFrameWork:appmodule_name, app_name = sys.argv[1].split(":")# module_name = "MyWebFrameWork"# app_name = "app"m = __import__(module_name)app = getattr(m, app_name)http_server = HTTPServer(app)# http_server.set_porthttp_server.bind(9000)http_server.start()if __name__ == '__main__':main()

 

 

框架的实现

MyWebFrameWork_v2.py

# coding:utf-8import time# 设置静态文件根目录
HTML_ROOT_DIR = "./html"class Application(object):"""框架的核心部分,也就是框架的主题程序,框架是通用的"""def __init__(self, urls):# 设置路由信息self.urls = urlsdef __call__(self, env, start_response):path = env.get("PATH_INFO", "/")# /static/index.htmlif path.startswith("/static"):# 要访问静态文件file_name = path[7:]# 打开文件,读取内容try:file = open(HTML_ROOT_DIR + file_name, "rb")except IOError:# 代表未找到路由信息,404错误status = "404 Not Found"headers = []start_response(status, headers)return "not found"else:file_data = file.read()file.close()status = "200 OK"headers = []start_response(status, headers)return file_data.decode("utf-8")for url, handler in self.urls:#("/ctime", show_ctime)if path == url:return handler(env, start_response)# 代表未找到路由信息,404错误status = "404 Not Found"headers = []start_response(status, headers)return "not found"def show_ctime(env, start_response):status = "200 OK"headers = [("Content-Type", "text/plain")]start_response(status, headers)return time.ctime()def say_hello(env, start_response):status = "200 OK"headers = [("Content-Type", "text/plain")]start_response(status, headers)return "hello frawework"def say_haha(env, start_response):status = "200 OK"headers = [("Content-Type", "text/plain")]start_response(status, headers)return "hello haha"urls = [("/", show_ctime),("/ctime", show_ctime),("/sayhello", say_hello),("/sayhaha", say_haha),]
app = Application(urls)

 

运行上述代码需要pycharm中配置

服务器程序--Edit Configurations....

 

转载于:https://www.cnblogs.com/wgDream/p/7536904.html

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

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

相关文章

Android中shape的使用

本人在美工方面一直是比较白痴的&#xff0c;对于一些颜色什么乱七八糟的非常头痛&#xff0c;但是在Android编程中这又是经常涉及到的东西&#xff0c;没办法&#xff0c;只有硬着头皮上。 Android中常常使用shape来定义控件的一些显示属性&#xff0c;今天看了一些shape的使用…

PHP遍历数组的几种方法

这三种方法中效率最高的是使用foreach语句遍历数组。从PHP4开始就引入了foreach结构&#xff0c;是PHP中专门为遍历数组而设计的语句&#xff0c;推荐大家使用。先分别介绍这几种方法 PHP中遍历数组有三种常用的方法&#xff1a; 一、使用for语句循环遍历数组&#xff1b; 二、…

Jmeter集合ant进行操作

1、下载ant包 地址【http://ant.apache.org/bindownload.cgi】 2、解压后&#xff0c;配置ant的环境变量&#xff0c;如下图 3、修改jmeter/extras中的build.xml的文件 代码如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?><project nam…

五种常见的 PHP 设计模式

设计模式只是为 Java™ 架构师准备的 —— 至少您可能一直这样认为。实际上&#xff0c;设计模式对于每个人都非常有用。如果这些工具不是 “架构太空人” 的专利&#xff0c;那么它们又是什么&#xff1f;为什么说它们在 PHP 应用程序中非常有用&#xff1f;本文解释了这些问题…

linux常见命令的常用方法示例

本文涉及命令&#xff1a;date,clock,hwclock,cal,ls,cd,pwd,tty,whereis,which,stat,echo,shutdown,halt,reboot,poweroff,who,w,whami部分命令结果等同&#xff0c;合到一起示例一、Date 打印或设置系统日期和时间1、date &#xff1a;查看当前系统日期和时间2、date %a:查看…

Day-17: 网络编程

---恢复内容开始--- 现有的互联网通讯方式&#xff0c;是服务器端的进程与客户端进程的通信。Python中进行网络编程&#xff0c;就是在Python程序本身这个进程内&#xff0c;连接别的服务器进程的通信端口进行通信。 互联网协议上包含了上百种协议标准&#xff0c;但是&#xf…

计算机应用基础教程作业脑图 车辆工程学院 冯大昕

转载于:https://www.cnblogs.com/FengTang/p/7553055.html

EasyDSS高性能流媒体服务器前端重构(五)- webpack + vue-router 开发单页面前端实现按需加载 - 副本...

为了让页面更快完成加载, 第一时间呈现给客户端, 也为了帮助客户端节省流量资源, 我们可以开启 vue-router 提供的按需加载功能, 让客户端打开页面时, 只自动加载必要的资源文件, 当客户端操作页面, 切换功能模块, 触发页面路由变化时, 再去加载相应需要的资源. 本系列博客的前…

解密阿里云七武器之高性能消息服务ONS

2019独角兽企业重金招聘Python工程师标准>>> 7月22日&#xff0c;首届阿里云分享日上&#xff0c;阿里云正式对外发布了企业级互联网架构解决方案&#xff0c;该服务由EDAS应用框架、ONS消息队列、DRDS分布式数据库组成&#xff0c;能有效解决企业上云后网站过载、性…

windows服务器下的ftp server搭建

软件下载链接&#xff1a;http://pan.baidu.com/s/1eQJbmUY ftpserver1.下载后打开。2.运行安装3.安装目录选择。这里我选择安装在C盘的FTP目录下&#xff0c;直接填写即可。这个安装目录可随意设置。4.安装启动。查看使用教程&#xff0c;添加用户名&#xff0c;设置密码&a…

WordPress获取当前分类ID的四种方法

WordPress获取当前分类ID的四种方法 时间: 2015-01-05 所属栏目: Wordpress教程 作者: WP管理员之家 关键词: wordpress,分类ID 关注热度&#xff1a; 4,346 次 (1条) WordPress获取当前分类ID的方法有很多&#xff0c;今天我来给大家总结一下吧,wordpress主题定制专家-WP管理…

EditPlus3 添加 PHP代码格式化

https://www.jb51.net/softs/23113.html 整合PHPCB到EditPlus&#xff1a; EidtPlus&#xff1a;工具》配置用户工具…》添加工具&#xff1a; 菜单文本&#xff1a;PHPCB 命令&#xff1a;浏览到PHPCB程序。 参数&#xff1a;--space-after-if --optimize-eol --space-aft…

1-17

今天很慵懒啊&#xff0c;啥事也没做&#xff0c;把高精度复习了一遍&#xff08;hdu1002&#xff09;。 首先俩字符串数组输入&#xff0c;然后按字符串的长度逆序转到整形数组里 &#xff08;主要是为了把数值的最低位移动到数组的最低位&#xff0c;方便进位&#xff09;&am…

FTP下载导致Zip解压失败的原因

情形&#xff1a;网关通过FTP下载快钱对账文件时通过Apache下commons-net的commons-net-3.5.jar进行封装&#xff0c;对账文件中有中文和英文的文字,大部分情况下能够下载成功&#xff0c;而且也能解压成功。但是偶尔会出现下载了zip的文件&#xff0c;但是解压失败的情况。解决…

zabbix通过JMX监控Tomcat及一些报错

软件包下载地址&#xff1a;Wget http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.11/bin/apache-tomcat-7.0.11.tar.gz#安装jdk:Mkdir /usr/lib/jvmTar xf jdk-7u45-linux-x64.gz -C /usr/lib/jvm#在profile追加以下内容 Vim /etc/profileJAVA_HOME"/usr/lib/jvm/j…

C++入门经典-例8.1-类的继承

1&#xff1a;继承是面向对象的主要特征&#xff08;此外还有封装和多态&#xff09;之一&#xff0c;它使得一个类可以从现有类中派生&#xff0c;而不必重新定义一个新类。继承的实质就是用已有的数据类型创建新的数据类型&#xff0c;并保留已有数据类型的特点&#xff0c;以…

有意思的PHP代码块-面试经典_无需整理

为什么80%的码农都做不了架构师&#xff1f;>>> 不使用PHP自带反转函数&#xff0c;将字符串反转。//不用自带函数将其反转 方法一 $str "This is PHP"; $strArr explode( ,$str); $count count($strArr)-1; for($i$count;$i>0;$i--){$revStr . $s…

iOS开发之UITableView中计时器的几种实现方式(NSTimer、DispatchSource、CADisplayLink)

最近工作比较忙&#xff0c;但是还是出来更新博客了。今天博客中所涉及的内容并不复杂&#xff0c;都是一些平时常见的一些问题&#xff0c;通过这篇博客算是对UITableView中使用定时器的几种方式进行总结。本篇博客会给出在TableView中使用NSTimer或者DispatchSourcer中常见的…

CentOS查看每个进程的网络流量

所需工具nethogs 安装&#xff1a;yum install -y nethogs 使用&#xff1a;nethogs eth0 sudo nethogs -s //按接收流量大小排序 如上图&#xff0c;PID一列就是进程的PID&#xff0c;PROGRAM就是显示进程或连接双方的端口号&#xff0c;前面红框是服务器的IP:端口&#xff0…

转:Java反射教程

原文来自于&#xff1a;http://www.importnew.com/9078.html 什么是反射&#xff1f;反射有什么用处&#xff1f; 1. 什么是反射&#xff1f; “反射&#xff08;Reflection&#xff09;能够让运行于JVM中的程序检测和修改运行时的行为。”这个概念常常会和内省&#xff08;Int…