WSGI (Web服务器网关接口):Web服务网关接口,是Python中定义的服务器程序和应用程序之间的接口。
Web程序开发中,一般分为服务器程序和应用程序。服务器程序负责对套接字服务的数据进行封装和整理,而应用程序则负责对Web请求进行逻辑处理。
Web应用本质上也是一个套接字服务器,用户的浏览器就是一个套接字客户端。
我们先用套接字编程实现一个简单的Web服务器:
进口套接字 def handle_request(客户端): buf=client.recv (1024) 打印(buf) 味精=癏TTP/1.1 200 OK \ r \ n \ r \ n”# HTTP头信息 客户端。发送((' % s ' %味精).encode ()) 味精=癏ello, World !” 客户端。发送((' % s ' %味精).encode ()) def main (): ip_port=(“localhost”, 8000年) 袜子=socket.socket(插座。AF_INET socket.SOCK_STREAM) sock.bind (ip_port) sock.listen (5) 而真正的: 康涅狄格州,addr=sock.accept () handle_request(康涅狄格州) conn.close () if __name__==癬_main__”: main () >之前上述代码中,主要()函数就是服务器函数,handle_request()就是应用程序。
下面我们再用python的wsgiref模块来实现跟上述代码一样的Web服务器:
从wsgiref。simple_server进口make_server def handle_request (env, res): res (“200 OK”,(“内容类型”,“text/html”))) 身体=" & lt; h2> Hello World ! & lt;/h2>” 返回(body.encode (“utf - 8”)) if __name__==癬_main__”: httpd=make_server(" ", 8000年,handle_request) 打印(“http服务> if __name__==癬_main__”: httpd=make_server(" ", 8000年,handle_request) 打印(“http服务> def make_server(主机、端口、应用,server_class=WSGIServer handler_class=WSGIRequestHandler): ”““创建一个新的WSGI服务器听> # BaseServer类的__init__()函数: def __init__(自我、server_address RequestHandlerClass): ”“”的构造函数。可以延长,不要覆盖。”“” 自我。server_address=server_address 自我。RequestHandlerClass=RequestHandlerClass 自我。__is_shut_down=threading.Event () 自我。__shutdown_request=False >之前# TCPServer类的__init__()函数: def __init__(自我、server_address RequestHandlerClass bind_and_activate=True): ”“”的构造函数。可以延长,不要覆盖。”“” BaseServer。__init__(自我、server_address RequestHandlerClass) 自我。套接字=socket.socket (self.address_family self.socket_type) 如果bind_and_activate: 试一试: self.server_bind () self.server_activate () 除了: self.server_close () 提高 >之前TCPServer类的初始化函数还调用了server_bind(自我),server_bind(自我)两个函数:
def server_bind(自我): ”““由构造函数调用绑定套接字。可能覆盖。”“” 如果self.allow_reuse_address: self.socket.setsockopt(套接字。SOL_SOCKET,插座。SO_REUSEADDR, 1) self.socket.bind (self.server_address) 自我。server_address=self.socket.getsockname () def self.server_activate(自我): ”“”由构造函数调用激活服务器。可能覆盖。”“” self.socket.listen (self.request_queue_size) >之前可以看到server.bind()函数调用了socket.bind()函数,而server_activate()调用了socket.listen()函数:
3, server.set_app(应用程序),此处传入网络请求的处理逻辑:
def set_app(自我、应用): 自我。应用=应用 >之前4, httpd.serve_forever()函数调用BaseServer类的_handle_request_noblock()函数处理多路请求:
def _handle_request_noblock(自我): 试一试: 请求,client_address=self.get_request () # get_request()调用了socket.accept()函数 除了OSError: 返回 如果自我。verify_request(请求,client_address): 试一试: 自我。client_address process_request(请求) 除了: 自我。client_address handle_error(请求) self.shutdown_request(请求) 其他: self.shutdown_request(请求)Python模块WSGI使用详解