python HTTPServer v2.0 (select应用)

HTTPServer v2.0

day12/http_server.py

  1. 主要功能 :
    【1】 接收客户端(浏览器)请求
    【2】 解析客户端发送的请求
    【3】 根据请求组织数据内容
    【4】 将数据内容形成http响应格式返回给浏览器
  2. 升级点 :
    【1】 采用IO并发,可以满足多个客户端同时发起请求情况
    【2】 做基本的请求解析,根据具体请求返回具体内容,同时满足客户端简单的非网页请求情况
3】 通过类接口形式进行功能封装

技术分析

  1. 使用tcp通信,基于http协议格式
  2. select io多路复用

结构:

​ 采用各类封装

类的接口设计:

  1. 在用户使用的角度进行流程设计
  2. 当需要完成的功能是一个比较大的概括的功能,可以提供继承方法,让别人使用时继承你的类
  3. 针对一个非常具体的功能,尽量帮用户实现更多的功能,让用户尽可能少的修改代码或者尽可能简单的使用
  4. 不能够替用户决定的属性,让用户传参
  5. 不能替用户决定的复杂功能,让用户去重写
  6. 确定功能,参数,使用方法
"""
http_server v2.0
io多路复用 和 http 训练
"""

from socket import *
from select import *


# 具体功能实现
class HTTPServer:
    def __init__(self, addr=(('0.0.0.0', 8888)), dir='./static'):
        self.addr = addr
        self.dir = dir
        # 多路复用列表
        self.rlist = []
        self.wlist = []
        self.xlist = []
        self.create_socket()
        self.bind()

    # 创建套接字
    def create_socket(self):
        self.sockfd = socket()
        self.sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)

    # 绑定地址
    def bind(self):
        self.sockfd.bind(self.addr)

    # 处理请求
    def handle(self, c):
        # 接收HTTP请求
        request = c.recv(4096)
        if not request:
            self.rlist.remove(c)
            c.close()
            return
        # 提取请求内容 splitlines将字节串按行分割
        request_line = request.splitlines()[0]
        print(request_line.decode())
        info = request_line.decode().split(' ')[1]
        print(c.getpeername(), ':', info)

        # 根据请求内容进行数据整理
        # 分为两类 1.请求网页 2.其他
        if info == '/' or info[-5:] == '.html':
            self.get_html(c,info)
        else:
            self.get_other(c)
        # self.rlist.remove(c)

    # 返回网页
    def get_html(self,c,info):
        if info =='/':
            # 请求主页
            filename = self.dir + '/index.html'
        else:
            filename = self.dir +info
        try:
            fd = open(filename,'rb')
        except Exception:
            # 网页不存在
            response = 'HTTP/1.1 404 Not Found\r\n'
            response += 'Content-type:text/html\r\n'
            response += '\r\n'
            response += '<h1>Sorry..页面不存在</h1>\r\n'
            response = response.encode()
        else:
            # 网页存在
            response = 'HTTP/1.1 200 OK\r\n'
            response += 'Content-type:text/html\r\n'
            response += '\r\n'
            response = response.encode()
            response += fd.read()
        finally:
            # 将响应放松给浏览器
            c.send(response)



    # 其他数据
    def get_other(self,c):
        response = 'HTTP/1.1 200 OK\r\n'
        response += 'Content-type:text/html\r\n'
        response += '\r\n'
        response += '<h1>Waiting for httpserver 3.0</h1>\r\n'
        response = response.encode()
        c.send(response)



    # 启动服务
    def serve_forever(self):
        self.sockfd.listen(3)
        print('Listen the port %d' % self.addr[1])
        # IO多路复用接收客户端请求
        self.rlist.append(self.sockfd)
        while True:
            rs, ws, xs = select(self.rlist, self.wlist, self.xlist)
            for r in rs:
                if r is self.sockfd:
                    c, addr = r.accept()
                    # print('Connect from', addr)
                    self.rlist.append(c)
                else:
                    self.handle(r)


# 用户使用HTTPServer
if __name__ == '__main__':
    """
    通过 HTTPServer 类快速搭建服务,展示自己的网页
    """
    # 用户决定的参数
    HOST = '0.0.0.0'
    PORT = 38383
    ADDR = ((HOST, PORT))
    # 网页存储位置
    DIR = 'static'
    # 实例化对象
    httpd = HTTPServer(ADDR, DIR)
    # 启动服务
    httpd.serve_forever()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值