Note7:网络编程之Web动态服务器
2018-03-06 22:02
141 查看
一,介绍
Web静态服务器的原理是浏览器发送一个请求给服务器,服务器接到请求后解析,然后返回一个响应报文给浏览器,浏览器通过渲染得到用户看到的页面。假如现在有一个要求,我们要求得到的页面是动态的,意思是不同时间可以访问到不同的页面内容。我们不可能时刻的去改写页面数据。这时如果让服务器返回给浏览器的数据是一个程序,那么程序自动执行,我们每次访问页面的时候,就可以得到的是不同的页面数据。即我们只要让服务器的返回消息体是一个程序的话,我们的Web动态服务器就可以实现了。
二,Web动态服务器实现原理:
服务器要执行一个程序的话,那么我们就要开始构造响应数据了。
实现Web动态服务器有一个WSGI协议,WSGI接口定义非常简单,它只要求Web开发者实现一个函数,就可以响应HTTP请求。
def application(env, start_response):
status = '200 OK'
header = [('content','txt')]
start_response(status, header)
return time.ctime()1.status是一个状态码,每个程序执行时所产生的状态码可能不同,所以要写在程序中,不能在服务器中定义
2.header是这个程序的的一些信息
3.status和header组成服务器的响应报文,所以通过start_response中把信息传给服务器,因此服务器要定义一个start_response函数来接收程序给服务器传的一些信息来组成响应报文
4.application函数中有一个env参数,它是一个字典类型,里面是服务器传给这个程序的请求报文(这个请求报文是浏览器给服务器的),而这个请求数据中的一些信息是对执行这个程序是有用的。
5.application函数返回给服务器的信息是一个响应体,因此响应头是通过start_response传给服务器的
三,简单的Web动态服务器
服务器:import socket
import re
import sys
from multiprocessing import Process
HTML_ROOT_DIR = '.\html'
WSGI_DIR = '.\wsgi'
class MyServer(object):
def __init__(self, port):
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def bind(self,port):
"""邦定端口"""
self.server.bind(('',port))
def start(self):
self.server.listen(10)
while True:
# 监听链接
conn, addr = self.server.accept()
p = Process(target=self.handle_request, args=(conn,))
p.start()
conn.close()
def handle_request(self, conn):
"""处理客户端的请求,找出其中的path,并将路径符转换为windows中的"""
recv_request = conn.recv(1024).decode()
# 客户端请求数据行首
request = recv_request.splitlines()
for line in request:
print(line)
request_start = request[0]
# 由于windows中的文件目录为‘\’,所以要将其中'/'替换为'\'
path = request_start.split()[1]
new_path = re.sub('/', r'\\', path)
self.response_info(conn, new_path)
def handle_response(self, status, headers):
"""将程序执行的返回的响应消息进行处理来作为本次服务器给浏览器的响应头"""
response_header ='HTTP/1.1 '+status+'\r\n'
for line in headers:
response_header += '%s: %s'%(line) + '\r\n'
self.response_header = response_header
def response_info(self, conn, path):
"""找出文件在服务器中的位置"""
if path.endswith('.py'):
#导入要执行的程序
m = __import__(path[1:-3])
#浏览器的请求数据传给程序
env = {}
#程序的执行通过application函数接口来执行,它返回的是一个响应消息体
response_body = m.application(env, self.handle_response)
info = self.response_header+'\r\n'+response_body
else:
filename = HTML_ROOT_DIR + path
if '\\' == path:
filename = '.\html\index.html'
print(filename)
# 若没有找到正确的文件,则报404 Not Found错误,找到了,则打开读取数据
try:
f = open(filename, 'rb')
response_body = f.read().decode()
4000
except IOError:
response_start = 'HTTP/1.1 404 Not Found\r\n'
response_head = 'server:My server\r\n'
response_body = 'the file is exist\r\n'
else:
response_start = 'HTTP/1.1 200 OK\r\n'
response_head = 'server:My server\r\n'
finally:
info = response_start + response_head + '\r\n' + response_body
conn.send(info.encode('utf-8'))
conn.close()
def main():
sys.path.insert(1, WSGI_DIR)
myserver = MyServer(8000)
myserver.start()
if __name__ == '__main__':
main()程序:import time
def application(env, handle_respose):
status = '200 OK'
headers = [('content', 'text')]
handle_respose(status, headers)
return time.ctime()
四,Web框架的编写
目录:
MyWebFrame:from MyWebServer import MyServer
import time
import re
HTML_DIR = '.\html'
class Application(object):
"""接口"""
def __init__(self, urls):
self.urls = urls
def __call__(self, env, start_response):
path = env.get('PATH_INFO')
#静态页面
if path.startswith('/static'):
#/static/index.html
filename = path[7:]
filename = re.sub('/', r'\\', filename)
print(filename)
try:
f = open(HTML_DIR + filename, 'rb')
data = f.read().decode()
f.close()
status = '200 OK'
headers = [('content', 'txt')]
start_response(status, headers)
return data
except IOError:
status = '404 Not Found'
headers = []
start_response(status, headers)
return 'Error 404 Not Found'
#动态页面
for url, handle in self.urls:
if url == path:
res = handle(env,start_response)
return res
status = '404 Not Found'
headers = []
start_response(status,headers)
return 'file is not exist'
def show_time(env, start_response):
status = '200 OK'
headers = [('content','text/plain')]
start_response(status,headers)
return time.ctime()
def say_hello(env, start_response):
status = '200 OK'
headers = [('content', 'text/plain')]
start_response(status, headers)
return 'hello word'.title()
if __name__ == '__main__':
urls = [('/ctime', show_time), ('/hello', say_hello),('/', show_time)]
app = Application(urls)
myServer = MyServer(app)
myServer.bind(8000)
myServer.start()MyWebServer:import socket
import re
from multiprocessing import Process
class MyServer(object):
""""""
def __init__(self, application):
"""把接口传到服务器中"""
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.app = application
def bind(self,port):
"""邦定端口"""
self.server.bind(('', port))
def start(self):
self.server.listen(100)
while True:
# 监听链接
conn, addr = self.server.accept()
p = Process(target=self.handle_request, args=(conn,))
p.start()
conn.close()
def handle_request(self, conn):
"""处理客户端的请求,找出其中的path,"""
recv_request = conn.recv(1024).decode()
# 客户端请求数据行首
try:
request = recv_request.splitlines()
for line in request:
print(line)
request_start = request[0]
path = request_start.split()[1]
self.response_info(conn, path)
except Exception:
pass
def handle_response(self, status, headers):
"""将响应的消息进行处理"""
response_header ='HTTP/1.1 '+status+'\r\n'
for line in headers:
response_header += '%s: %s'%(line) + '\r\n'
self.response_header = response_header
def response_info(self, conn, path):
"""找出文件在服务器中的位置"""
env = {'PATH_INFO': path}
response_body = self.app(env, self.handle_response)
info = self.response_header+'\r\n'+response_body
conn.send(info.encode('utf-8'))
conn.close()
Web静态服务器的原理是浏览器发送一个请求给服务器,服务器接到请求后解析,然后返回一个响应报文给浏览器,浏览器通过渲染得到用户看到的页面。假如现在有一个要求,我们要求得到的页面是动态的,意思是不同时间可以访问到不同的页面内容。我们不可能时刻的去改写页面数据。这时如果让服务器返回给浏览器的数据是一个程序,那么程序自动执行,我们每次访问页面的时候,就可以得到的是不同的页面数据。即我们只要让服务器的返回消息体是一个程序的话,我们的Web动态服务器就可以实现了。
二,Web动态服务器实现原理:
服务器要执行一个程序的话,那么我们就要开始构造响应数据了。
实现Web动态服务器有一个WSGI协议,WSGI接口定义非常简单,它只要求Web开发者实现一个函数,就可以响应HTTP请求。
def application(env, start_response):
status = '200 OK'
header = [('content','txt')]
start_response(status, header)
return time.ctime()1.status是一个状态码,每个程序执行时所产生的状态码可能不同,所以要写在程序中,不能在服务器中定义
2.header是这个程序的的一些信息
3.status和header组成服务器的响应报文,所以通过start_response中把信息传给服务器,因此服务器要定义一个start_response函数来接收程序给服务器传的一些信息来组成响应报文
4.application函数中有一个env参数,它是一个字典类型,里面是服务器传给这个程序的请求报文(这个请求报文是浏览器给服务器的),而这个请求数据中的一些信息是对执行这个程序是有用的。
5.application函数返回给服务器的信息是一个响应体,因此响应头是通过start_response传给服务器的
三,简单的Web动态服务器
服务器:import socket
import re
import sys
from multiprocessing import Process
HTML_ROOT_DIR = '.\html'
WSGI_DIR = '.\wsgi'
class MyServer(object):
def __init__(self, port):
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def bind(self,port):
"""邦定端口"""
self.server.bind(('',port))
def start(self):
self.server.listen(10)
while True:
# 监听链接
conn, addr = self.server.accept()
p = Process(target=self.handle_request, args=(conn,))
p.start()
conn.close()
def handle_request(self, conn):
"""处理客户端的请求,找出其中的path,并将路径符转换为windows中的"""
recv_request = conn.recv(1024).decode()
# 客户端请求数据行首
request = recv_request.splitlines()
for line in request:
print(line)
request_start = request[0]
# 由于windows中的文件目录为‘\’,所以要将其中'/'替换为'\'
path = request_start.split()[1]
new_path = re.sub('/', r'\\', path)
self.response_info(conn, new_path)
def handle_response(self, status, headers):
"""将程序执行的返回的响应消息进行处理来作为本次服务器给浏览器的响应头"""
response_header ='HTTP/1.1 '+status+'\r\n'
for line in headers:
response_header += '%s: %s'%(line) + '\r\n'
self.response_header = response_header
def response_info(self, conn, path):
"""找出文件在服务器中的位置"""
if path.endswith('.py'):
#导入要执行的程序
m = __import__(path[1:-3])
#浏览器的请求数据传给程序
env = {}
#程序的执行通过application函数接口来执行,它返回的是一个响应消息体
response_body = m.application(env, self.handle_response)
info = self.response_header+'\r\n'+response_body
else:
filename = HTML_ROOT_DIR + path
if '\\' == path:
filename = '.\html\index.html'
print(filename)
# 若没有找到正确的文件,则报404 Not Found错误,找到了,则打开读取数据
try:
f = open(filename, 'rb')
response_body = f.read().decode()
4000
except IOError:
response_start = 'HTTP/1.1 404 Not Found\r\n'
response_head = 'server:My server\r\n'
response_body = 'the file is exist\r\n'
else:
response_start = 'HTTP/1.1 200 OK\r\n'
response_head = 'server:My server\r\n'
finally:
info = response_start + response_head + '\r\n' + response_body
conn.send(info.encode('utf-8'))
conn.close()
def main():
sys.path.insert(1, WSGI_DIR)
myserver = MyServer(8000)
myserver.start()
if __name__ == '__main__':
main()程序:import time
def application(env, handle_respose):
status = '200 OK'
headers = [('content', 'text')]
handle_respose(status, headers)
return time.ctime()
四,Web框架的编写
目录:
MyWebFrame:from MyWebServer import MyServer
import time
import re
HTML_DIR = '.\html'
class Application(object):
"""接口"""
def __init__(self, urls):
self.urls = urls
def __call__(self, env, start_response):
path = env.get('PATH_INFO')
#静态页面
if path.startswith('/static'):
#/static/index.html
filename = path[7:]
filename = re.sub('/', r'\\', filename)
print(filename)
try:
f = open(HTML_DIR + filename, 'rb')
data = f.read().decode()
f.close()
status = '200 OK'
headers = [('content', 'txt')]
start_response(status, headers)
return data
except IOError:
status = '404 Not Found'
headers = []
start_response(status, headers)
return 'Error 404 Not Found'
#动态页面
for url, handle in self.urls:
if url == path:
res = handle(env,start_response)
return res
status = '404 Not Found'
headers = []
start_response(status,headers)
return 'file is not exist'
def show_time(env, start_response):
status = '200 OK'
headers = [('content','text/plain')]
start_response(status,headers)
return time.ctime()
def say_hello(env, start_response):
status = '200 OK'
headers = [('content', 'text/plain')]
start_response(status, headers)
return 'hello word'.title()
if __name__ == '__main__':
urls = [('/ctime', show_time), ('/hello', say_hello),('/', show_time)]
app = Application(urls)
myServer = MyServer(app)
myServer.bind(8000)
myServer.start()MyWebServer:import socket
import re
from multiprocessing import Process
class MyServer(object):
""""""
def __init__(self, application):
"""把接口传到服务器中"""
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.app = application
def bind(self,port):
"""邦定端口"""
self.server.bind(('', port))
def start(self):
self.server.listen(100)
while True:
# 监听链接
conn, addr = self.server.accept()
p = Process(target=self.handle_request, args=(conn,))
p.start()
conn.close()
def handle_request(self, conn):
"""处理客户端的请求,找出其中的path,"""
recv_request = conn.recv(1024).decode()
# 客户端请求数据行首
try:
request = recv_request.splitlines()
for line in request:
print(line)
request_start = request[0]
path = request_start.split()[1]
self.response_info(conn, path)
except Exception:
pass
def handle_response(self, status, headers):
"""将响应的消息进行处理"""
response_header ='HTTP/1.1 '+status+'\r\n'
for line in headers:
response_header += '%s: %s'%(line) + '\r\n'
self.response_header = response_header
def response_info(self, conn, path):
"""找出文件在服务器中的位置"""
env = {'PATH_INFO': path}
response_body = self.app(env, self.handle_response)
info = self.response_header+'\r\n'+response_body
conn.send(info.encode('utf-8'))
conn.close()
相关文章推荐
- 利用python编写设计多线程web服务器(计算机网络_自顶向下第六版_第二章1和4的编程作业)
- Java网络编程 - 浅析web服务器与浏览器的实现原理
- Socket网络编程--简单Web服务器(5)
- 网络编程知识(8)--使用Nginx搭建WEB服务器
- Android中网络编程以及与服务器上Web项目的基础交互
- Socket网络编程--简单Web服务器(3)
- Socket网络编程--简单Web服务器(4)
- Socket网络编程--简单Web服务器(1)
- JavaWeb之Servlet&网络访问服务器编程
- [C# 网络编程 自定义Web服务器
- Note6:网络编程之web静态服务器
- [Python]网络编程--web服务器
- Socket网络编程--简单Web服务器(2)
- Socket网络编程--简单Web服务器(6)
- Java网络编程 - 浅析web服务器与浏览器的实现原理
- WIN网络编程-重叠I/0服务器设计
- Linux网络编程--服务器模型
- 网络编程学习_简单的多进程并发服务器/客户端
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现