HTTPServer

HTTPServer

参考代码: day19/HTTPServer

功能

httpserver部分
获取http请求
解析http请求
将请求发送给WebFrame
从WebFrame接收反馈数据
将数据组织为Response格式发送给客户端

WebFrame部分
从httpserver接收具体请求
根据请求进行逻辑处理和数据处理
将需要的数据反馈给httpserver

特点
采用httpserver和应用处理分离的模式,降低了耦合度
采用了用户配置文件的思路
webframe部分采用了模拟后端框架的处理方法

技术点
httpserver部分需要与两端建立通信
webFrame部分采用多路复用接收并发请求
数据传递使用json格式

项目结构:

				|--httpserver --HttpServer.py (主程序)
			     |			--config (httpserver配置)

project–|
|
|
|–WebFrame --WebFrame.py (主程序代码)
–static (存放静态网页)
–views.py ( 应用处理程序)
–urls.py (存放路由)
–settings (框架配置)

交互数据格式协议

httpserver–>webframe {method:‘GET’,info:’/’}

webframe–>httpserver {status:‘200’,data:‘ccccc’}

"""
httpserver部分配置文件
"""

# [http server address]  被浏览器访问
HOST           = '0.0.0.0'
PORT           = 8000

# 是否调试模式
DEBUG          = True

# [后端应用地址] 表明配合的webframe地址
frame_ip       = '127.0.0.1'
frame_port     = 8080

"""
httpserver部分主程序
获取http请求
解析http请求
将请求发送给WebFrame
从WebFrame接收反馈数据
将数据组织为Response格式发送给客户端
"""
from socket import *
from threading import Thread
from config import *
import re
import json


# 与后端应用交互
def connect_frame(env):
    """
    将请求发送给WebFrame
    从WebFrame接收反馈数据
    """
    s = socket()
    try:
        s.connect((frame_ip, frame_port))
    except Exception as e:
        print(e)
        return
    # 发送json请求
    data = json.dumps(env)
    s.send(data.encode())
    # 获取返回的数据 (json格式)
    data = s.recv(1024 * 1024 * 10).decode()
    if data:
        try:
            result = json.loads(data)  # 返回字典
        except:
            pass
        return result


# 主体功能写入类
class HTTPServer:
    def __init__(self):
        self.address = (HOST, PORT)
        self.create_socket()
        self.bind()

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

    # 绑定地址
    def bind(self):
        # 有些属性可以在调用函数时再生产
        self.host = HOST
        self.port = PORT
        self.sock.bind(self.address)

    # 服务启动函数 (多线程并发)
    def serve_forever(self):
        self.sock.listen(3)
        print("Listen the port %d" % self.port)
        while True:
            connfd, addr = self.sock.accept()
            print("Connect from", addr)
            t = Thread(target=self.handle,
                       args=(connfd,))
            t.setDaemon(True)
            t.start()

    # 处理具体的浏览器请求
    def handle(self, connfd):
        # http请求
        request = connfd.recv(4096).decode()
        pattern = r"(?P<method>[A-Z]+)\s+(?P<info>/\S*)"
        try:
            env = re.match(pattern, request).groupdict()
        except:
            connfd.close()
            return
        else:
            # 与webframe交互 (数据字典/None)
            data = connect_frame(env)
            if data:
                self.response(connfd, data)

    # 组织响应格式
    def response(self, connfd, data):
        # data->{'status':'200','data':'zzzz'}
        if data['status'] == '200':
            res="HTTP/1.1 200 OK\r\n"
            res+="Content-Type:text/html\r\n"
            res+="\r\n"
            res+=data['data']
        elif data['status'] == '404':
            res="HTTP/1.1 404 Not Found\r\n"
            res+="Content-Type:text/html\r\n"
            res+="\r\n"
            res+=data['data']
        connfd.send(res.encode()) # 响应给浏览器


if __name__ == '__main__':
    httpd = HTTPServer()
    httpd.serve_forever()  # 启动服务```

```python
from socket import *
import json

s = socket()
s.bind(('127.0.0.1',8080))
s.listen(3)

while True:
    c,addr = s.accept()
    data = c.recv(1024).decode()
    print(data)
    data = json.dumps({'status':'200','data':'OK'})
    c.send(data.encode())```
```python
"""
路由选择模块
"""
from views import *

urls = [
    # 如果你访问'/time'这个路径,我有数据,
    # 用show_time这个方法给你提供
    ("/time",show_time),
    ("/hello",hello),
    ("/bye",bye),
"""
webframe 配置文件
"""
# [frame address]
frame_ip = '0.0.0.0'
frame_port = 8080

# [debug]
DEBUG = True

# [save html pages]
STATIC_DIR = "./static"

"""
数据处理模块
"""
def show_time():
    import time
    return time.ctime()

def hello():
    return "Hello world"

def bye():
    return "good bye"
"""
webframe  模拟网站应用做数据处理

从httpserver接收具体请求
根据请求进行逻辑处理和数据处理
将需要的数据反馈给httpserver
"""
from socket import *
import json
from threading import Thread
from settings import *
from urls import *


# 应用类
class Application:
    def __init__(self):
        self.host = frame_ip
        self.port = frame_port
        self.address = (frame_ip, frame_port)
        self.sock = socket()
        self.sock.setsockopt(SOL_SOCKET,
                             SO_REUSEADDR,
                             DEBUG)
        self.sock.bind(self.address)

    def start(self):
        self.sock.listen(3)
        print("Running web frame %d" % self.port)
        while True:
            connfd, addr = self.sock.accept()
            print("Connect from", addr)
            t = Thread(target=self.handle,
                       args=(connfd,))
            t.setDaemon(True)
            t.start()

    # 具体处理请求
    def handle(self, connfd):
        request = connfd.recv(1024).decode()
        request = json.loads(request)  # 请求字典
        # request --> {'method':'GET','info':'XXX'}
        # 判定请求类型
        if request['method'] == 'GET':
            if request['info'] == '/' or request['info'][-5:] == '.html':
                response = self.get_html(request['info'])
            else:
                response = self.get_data(request['info'])
        elif request['method'] == 'POST':
            pass
        # 将数据/网页给 httpserver
        # response => {'status':'200','data':'xxx'}
        response = json.dumps(response)
        connfd.send(response.encode())
        connfd.close()

    # 网页处理
    def get_html(self,info):
        if info == '/':
            filename = STATIC_DIR + '/index.html'
        else:
            filename = STATIC_DIR + info
        try:
            f = open(filename)
        except Exception as e:
            with open(STATIC_DIR+"/404.html") as fd:
                data = fd.read()
            return {'status':'404','data':data}
        else:
            data = f.read()
            f.close()
            return {'status':'200','data':data}

    # 其他处理
    def get_data(self,info):
        for url,func in urls:
            if url == info:
                return {'status':'200','data':func()}
        return {'status':'404','data':"Sorry..."}


if __name__ == '__main__':
    app = Application()
    app.start()  # 启动应用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值