pythonweb服务器编程(四)
Web动态服务器-1
#coding=utf-8
import socket
import sys
from multiprocessing import Process
import re class WSGIServer(object): addressFamily = socket.AF_INET
socketType = socket.SOCK_STREAM
requestQueueSize = 5 def __init__(self, serverAddress):
#创建一个tcp套接字
self.listenSocket = socket.socket(self.addressFamily,self.socketType)
#允许重复使用上次的套接字绑定的port
self.listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
#绑定
self.listenSocket.bind(serverAddress)
#变为被动,并制定队列的长度
self.listenSocket.listen(self.requestQueueSize) self.servrName = "localhost"
self.serverPort = serverAddress[1] def serveForever(self):
'循环运行web服务器,等待客户端的链接并为客户端服务'
while True:
#等待新客户端到来
self.clientSocket, client_address = self.listenSocket.accept() #方法2,多进程服务器,并发服务器于多个客户端
newClientProcess = Process(target = self.handleRequest)
newClientProcess.start() #因为创建的新进程中,会对这个套接字+1,所以需要在主进程中减去依次,即调用一次close
self.clientSocket.close() def setApp(self, application):
'设置此WSGI服务器调用的应用程序入口函数'
self.application = application def handleRequest(self):
'用一个新的进程,为一个客户端进行服务'
self.recvData = self.clientSocket.recv(2014)
requestHeaderLines = self.recvData.splitlines()
for line in requestHeaderLines:
print(line) httpRequestMethodLine = requestHeaderLines[0]
getFileName = re.match("[^/]+(/[^ ]*)", httpRequestMethodLine).group(1)
print("file name is ===>%s"%getFileName) #for test if getFileName[-3:] != ".py": if getFileName == '/':
getFileName = documentRoot + "/index.html"
else:
getFileName = documentRoot + getFileName print("file name is ===2>%s"%getFileName) #for test try:
f = open(getFileName)
except IOError:
responseHeaderLines = "HTTP/1.1 404 not found\r\n"
responseHeaderLines += "\r\n"
responseBody = "====sorry ,file not found===="
else:
responseHeaderLines = "HTTP/1.1 200 OK\r\n"
responseHeaderLines += "\r\n"
responseBody = f.read()
f.close()
finally:
response = responseHeaderLines + responseBody
self.clientSocket.send(response)
self.clientSocket.close()
else: #根据接收到的请求头构造环境变量字典
env = {} #调用应用的相应方法,完成动态数据的获取
bodyContent = self.application(env, self.startResponse) #组织数据发送给客户端
self.finishResponse(bodyContent) def startResponse(self, status, response_headers):
serverHeaders = [
('Date', 'Tue, 31 Mar 2016 10:11:12 GMT'),
('Server', 'WSGIServer 0.2'),
]
self.headers_set = [status, response_headers + serverHeaders] def finishResponse(self, bodyContent):
try:
status, response_headers = self.headers_set
#response的第一行
response = 'HTTP/1.1 {status}\r\n'.format(status=status)
#response的其他头信息
for header in response_headers:
response += '{0}: {1}\r\n'.format(*header)
#添加一个换行,用来和body进行分开
response += '\r\n'
#添加发送的数据
for data in bodyContent:
response += data self.clientSocket.send(response)
finally:
self.clientSocket.close() #设定服务器的端口
serverAddr = (HOST, PORT) = '', 8888
#设置服务器静态资源的路径
documentRoot = './html'
#设置服务器动态资源的路径
pythonRoot = './wsgiPy' def makeServer(serverAddr, application):
server = WSGIServer(serverAddr)
server.setApp(application)
return server def main(): if len(sys.argv) < 2:
sys.exit('请按照要求,指定模块名称:应用名称,例如 module:callable') #获取module:callable
appPath = sys.argv[1]
#根据冒号切割为module和callable
module, application = appPath.split(':')
#添加路径套sys.path
sys.path.insert(0, pythonRoot)
#动态导入module变量中指定的模块
module = __import__(module)
#获取module变量中指定的模块的,application变量指定的属性
application = getattr(module, application)
httpd = makeServer(serverAddr, application)
print('WSGIServer: Serving HTTP on port %d ...\n'%PORT)
httpd.serveForever() if __name__ == '__main__':
main()
应用程序示例
mport time def app(environ, start_response):
status = '200 OK'
response_headers = [('Content-Type', 'text/plain')]
start_response(status, response_headers)
return [str(environ)+'==Hello world from a simple WSGI application!--->%s\n'%time.ctime()]
Web动态服务器-2-传递数据给应用
#coding=utf-8
import socket
import sys
from multiprocessing import Process
import re class WSGIServer(object): addressFamily = socket.AF_INET
socketType = socket.SOCK_STREAM
requestQueueSize = 5 def __init__(self, serverAddress):
#创建一个tcp套接字
self.listenSocket = socket.socket(self.addressFamily,self.socketType)
#允许重复使用上次的套接字绑定的port
self.listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
#绑定
self.listenSocket.bind(serverAddress)
#变为被动,并制定队列的长度
self.listenSocket.listen(self.requestQueueSize) self.servrName = "localhost"
self.serverPort = serverAddress[1] def serveForever(self):
'循环运行web服务器,等待客户端的链接并为客户端服务'
while True:
#等待新客户端到来
self.clientSocket, client_address = self.listenSocket.accept() #方法2,多进程服务器,并发服务器于多个客户端
newClientProcess = Process(target = self.handleRequest)
newClientProcess.start() #因为创建的新进程中,会对这个套接字+1,所以需要在主进程中减去依次,即调用一次close
self.clientSocket.close() def setApp(self, application):
'设置此WSGI服务器调用的应用程序入口函数'
self.application = application def handleRequest(self):
'用一个新的进程,为一个客户端进行服务'
self.recvData = self.clientSocket.recv(2014)
requestHeaderLines = self.recvData.splitlines()
for line in requestHeaderLines:
print(line) httpRequestMethodLine = requestHeaderLines[0]
getFileName = re.match("[^/]+(/[^ ]*)", httpRequestMethodLine).group(1)
print("file name is ===>%s"%getFileName) #for test if getFileName[-3:] != ".py": if getFileName == '/':
getFileName = documentRoot + "/index.html"
else:
getFileName = documentRoot + getFileName print("file name is ===2>%s"%getFileName) #for test try:
f = open(getFileName)
except IOError:
responseHeaderLines = "HTTP/1.1 404 not found\r\n"
responseHeaderLines += "\r\n"
responseBody = "====sorry ,file not found===="
else:
responseHeaderLines = "HTTP/1.1 200 OK\r\n"
responseHeaderLines += "\r\n"
responseBody = f.read()
f.close()
finally:
response = responseHeaderLines + responseBody
self.clientSocket.send(response)
self.clientSocket.close()
else:
#处理接收到的请求头
self.parseRequest() #根据接收到的请求头构造环境变量字典
env = self.getEnviron() #调用应用的相应方法,完成动态数据的获取
bodyContent = self.application(env, self.startResponse) #组织数据发送给客户端
self.finishResponse(bodyContent) def parseRequest(self):
'提取出客户端发送的request'
requestLine = self.recvData.splitlines()[0]
requestLine = requestLine.rstrip('\r\n')
self.requestMethod, self.path, self.requestVersion = requestLine.split(" ") def getEnviron(self):
env = {}
env['wsgi.version'] = (1, 0)
env['wsgi.input'] = self.recvData
env['REQUEST_METHOD'] = self.requestMethod # GET
env['PATH_INFO'] = self.path # /index.html
return env def startResponse(self, status, response_headers, exc_info=None):
serverHeaders = [
('Date', 'Tue, 31 Mar 2016 10:11:12 GMT'),
('Server', 'WSGIServer 0.2'),
]
self.headers_set = [status, response_headers + serverHeaders] def finishResponse(self, bodyContent):
try:
status, response_headers = self.headers_set
#response的第一行
response = 'HTTP/1.1 {status}\r\n'.format(status=status)
#response的其他头信息
for header in response_headers:
response += '{0}: {1}\r\n'.format(*header)
#添加一个换行,用来和body进行分开
response += '\r\n'
#添加发送的数据
for data in bodyContent:
response += data self.clientSocket.send(response)
finally:
self.clientSocket.close() #设定服务器的端口
serverAddr = (HOST, PORT) = '', 8888
#设置服务器静态资源的路径
documentRoot = './html'
#设置服务器动态资源的路径
pythonRoot = './wsgiPy' def makeServer(serverAddr, application):
server = WSGIServer(serverAddr)
server.setApp(application)
return server def main(): if len(sys.argv) < 2:
sys.exit('请按照要求,指定模块名称:应用名称,例如 module:callable') #获取module:callable
appPath = sys.argv[1]
#根据冒号切割为module和callable
module, application = appPath.split(':')
#添加路径套sys.path
sys.path.insert(0, pythonRoot)
#动态导入module变量中指定的模块
module = __import__(module)
#获取module变量中制定的模块的application变量指定的属性
application = getattr(module, application)
httpd = makeServer(serverAddr, application)
print('WSGIServer: Serving HTTP on port {port} ...\n'.format(port=PORT))
httpd.serveForever() if __name__ == '__main__':
main()

pythonweb服务器编程(四)的更多相关文章
- linux高性能服务器编程 (四) --TCP/IP通信案例
第四章 TCP/IP通信案例 HTTP代理服务器的大致工作原理 在HTTP通信链上,客户端和服务器之间通常存在某些中转代理服务器.它们提供对目标资源的中转访问.一个HTTP请求可能被多个 ...
- pythonweb服务器编程(三)
Web静态服务器-2-显示需要的页面 #coding=utf-8 import socket from multiprocessing import Process import re def han ...
- pythonweb服务器编程(二)
Web静态服务器-1-显示固定的页面 #coding=utf-8 import socket from multiprocessing import Process def handleClient( ...
- pythonweb服务器编程(一)
HTTP协议简介 1. 使用谷歌/火狐浏览器分析 在Web应用中,服务器把网页传给浏览器,实际上就是把网页的HTML代码发送给浏览器,让浏览器显示出来.而浏览器和服务器之间的传输协议是HTTP,所以: ...
- c++游戏服务器编程学习笔记(一)TCP/IP
1. c++游戏服务器编程c++运行效率非常高2. TCP传输控制协议IP网际协议Socket 3.Linux 乌班图开源第三方库BOOST 4.80%游戏服务器端用C++工作量最大的地方是具体的游戏 ...
- 服务器编程入门(7)I/O复用
问题聚焦: 前篇提到了I/O处理单元的四种I/O模型. 本篇详细介绍实现这些I/O模型所用到的相关技术. 核心思想:I/O复用 使用情景: 客户端程序要同时处理多个socket ...
- 服务器编程入门(3)TCP协议详解
问题聚焦: 本节从如下四个方面讨论TCP协议: TCP头部信息:指定通信的源端端口号.目的端端口号.管理TCP连接,控制两个方向的数据流 TCP状态转移过程:TCP连接的任意一 ...
- Linux 高性能服务器编程——多进程编程
问题聚焦: 进程是Linux操作系统环境的基础. 本篇讨论以下几个内容,同时也是面试经常被问到的一些问题: 1 复制进程映像的fork系统调用和替换进程映像的exec系列系统调 ...
- Linux 高性能服务器编程——I/O复用
问题聚焦: 前篇提到了I/O处理单元的四种I/O模型. 本篇详细介绍实现这些I/O模型所用到的相关技术. 核心思想:I/O复用 使用情景: 客户端程序要同时处理多个socket ...
随机推荐
- Lua中,泛型for循环遍历table时,ipairs和pairs的区别
为了看出两者的区别,首先定义一个table: a={"Hello","World";a=1,b=2,z=3,x=10,y=20;"Good" ...
- BZOJ 2818 Gcd(欧拉函数+质数筛选)
2818: Gcd Time Limit: 10 Sec Memory Limit: 256 MB Submit: 9108 Solved: 4066 [Submit][Status][Discu ...
- Redis都有哪些数据类型
string 这是最基本的类型了,就是普通的set和get,做简单的kv缓存 hash 这个是类似map的一种结构,这个一般就是可以将结构化的数据,比如一个对象(前提是这个对象没嵌套其他的对象)给缓存 ...
- [转] react-router4 + webpack Code Splitting
项目升级为react-router4后,就尝试着根据官方文档进行代码分割.https://reacttraining.com/react-router/web/guides/code-splittin ...
- 重排DL
题解: https://www.luogu.org/problemnew/show/T51442 从这题上还是学到不少东西.. 以前并没有写过ex-bsgs 正好拿这个复习中国剩余定理和bsgs了(我 ...
- tasksetCPU亲和力&docke容器资源限制
[taskset详解] taskset设置cpu亲和力,taskset能够将一个或者多个进程绑定到一个或者多个处理器上运行 参数: 选项: -a, --all-tasks 在给定 pid 的所有任务( ...
- nginx配置2
第四节 nginx 配置文件 1 keepalive_timeout 65; 设定保存长久连接时长 0代表禁止, 若不设置默认是75s 2keepalive_requests nu; 在一 ...
- jav实验二
实验内容 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承.多态 3.初步掌握UML建模 4.熟悉S.O.L.I.D原则 5.了解设计模式 实验内容 1.参考Intellj ID ...
- rc.local(ubuntu18.04)
系统自带服务/lib/systemd/system/rc-local.service 软连接为 /lib/systemd/system/rc.local.service -> rc-local. ...
- 解析eBay BASE模式、去哪儿及蘑菇街分布式架构
目录:问题分析概念解读Most Simple原理解读eBey.去哪儿.蘑菇街分布式事务案例分析 参考资料 1.问题解析 要想做架构,必须识别出问题,即是谁的问题,什么问题.明显的,分布式架构解决 ...