python wsgi学习笔记

目的:搭建最简单的服务器框架(访问本地静态和动态资源)

一、大致思路:

        1、创建监听套接字

        2、绑定本地信息(IP和port)

        3、使用listen改变监听状态

        4、等待客户端(浏览器)的链接,并创建为客户端服务的服务套接字(使用多进程调用服务方法为客户端服务)

        5、服务方法:获取客户端发送的数据>>>使用正则表达式匹配客户端发送的信息,获得服务端需要的信息

>>>访问静态网页,直接本地匹配资源地址,读取并发送给客户端(浏览器) 

>>>访问动态资源,调用框架的application方法,获取框架返回的数据,组装成响应数据,发送给客户端(浏览器) 

上代码:Wsgi_Server.py

from socket import *
import re,multiprocessing,time
import mini_frame

class WSGIServer(object):
    def __init__(self):
        # 1、创建监听套接字
        self.server_socket = socket(AF_INET, SOCK_STREAM)
        self.server_socket.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
        # self.server_socket.setblocking(False)
        # 2、绑定本地IP和port信息,本地信息使用元组格式
        self.server_socket.bind(('', 8080))
        # 3、使用listen改变监听状态,设置监听容量
        self.server_socket.listen(128)

    def client_sever(self,new_socket):
        # 5、获取客户端发送的信息,并设置接收数据字节大小
        request = new_socket.recv(1024).decode('utf-8')
        # 6、使用正则表达式匹配客户端发送的信息,获得服务端需要的信息,本地匹配资源地址
        g = re.match(r'[^/]*/+([^ ]*)\s+', request)
        if g:
            file_name = g.group(1)
        # 7、根据匹配结果,在本地进行操作
        # 打开本地资源,读取本地数据作为响应体
        if not file_name.endswith('.py'):
            try:  # 执行代码
                with open(file_name, 'rb') as f:
                    response_body = f.read()
            except:  # 发生异常时执行
                response_body = '<h1>hello world! not found</h1>'.encode('utf-8')
            finally:  # 不管有没有异常时,都会执行的代码
                response_header = 'HTTP/1.1\r\n'
                response_header += '\r\n'
                print(file_name)
                # 组装本地数据
                response = response_header.encode('utf-8') + response_body
                # 8、发送匹配后的本地资源给客户端
                new_socket.send(response)
                # 9、关闭客户端套接字,结束服务,等待下一个客户端链接。
                new_socket.close()
        else:
            # 调用框架的application方法,传递字典和类方法,支持wsgi协议
            env=dict()
            env['path_info'] = file_name
            response_body = mini_frame.application(env,self.start_response)

            # 组装响应头,注意,每行数据后面必须加 \r\n
            response_header = 'HTTP/1.1 {} \r\n'.format(self.status)
            
            for i in self.hearders:
                response_header += '{}:{}\r\n'.format(i[0],i[1])
                
            response_header += '\r\n'
            
            response =response_header + response_body
            new_socket.send(response.encode('utf-8'))
        # 9、关闭客户端套接字,结束服务,等待下一个客户端链接。
        new_socket.close()

    def start_response(self,status,hearders):
        # 保存框架返回的状态码和响应头,为类属性,方便后续调用
        self.status = status
        self.hearders = hearders

    def run_forever(self):
        while True:
            # 4、接收服务端链接,创建为客户端服务的客户端套接字
            new_socket, client_addr = self.server_socket.accept()
            # 创建进程为客户端服务
            p=multiprocessing.Process(target=self.client_sever,args=(new_socket,))
            p.start()
            # 关闭客户套接字
            new_socket.close()

def main():
    '''控制整体,创建一个web服务器对象,然后调用一个方法来执行'''
    w=WSGIServer()
    w.run_forever()

if __name__ == '__main__':
    main()

mini_frame.py

import time

def login():
	return '这是登录页,当前时间:{}'.format(time.ctime())
def index():
	return '这是主页,当前时间:{}'.format(time.ctime())

def application(env,start_response):
	# 调用传递过来的方法,返回响应状态码和头部信息
	start_response('200 OK',[('Content-Type','text/html;charset=UTF-8')])
	if env['path_info'] == 'login.py':
		return login()
	elif env['path_info'] == 'index.py':
		return index()
	else:
		return 'hello world!冬天来了的body'

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值