截取某服务器的请求_简单Web服务器-网游服务器

可以动态根据用户的输入,发送指定的内容的页面

主体代码

#!/usr/bin/env python
# encoding: utf-8
# @Time    : 2019/10/10 11:57 AM
# @Author  : Li Xinjian  
# @File    : 12_简单Web服务器_网游服务器.py


"""
1、在类的初始化方法中配置当前的项目
{"2048": "./2048", "植物大战僵尸": "zwdzjs-v1", ...}

2、给类增加一个初始化项目配置的方法 init_project()
2.1  显示所有可以发布的游戏 菜单
2.2  接收用户的选择
2.3  保存用户选择的游戏对应的本地目录

3、更改Web服务器打开的文件目录

"""


import socket
from application import app
import sys
# 目标:封装为类,用start()方法启动服务器


class WebServer(object):

    def __init__(self, port):
        # 1、导入模块
        # 2、创建套接字
        tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # 3、设置地址重用
        tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

        # 4、绑定端口
        tcp_server_socket.bind(("", port))

        # 5、设置监听,让套接字由主动变为变得接收
        tcp_server_socket.listen(128)
        self.tcp_server_socket = tcp_server_socket

        # 保存要发布的项目的路径
        self.current_dir = ""

        self.project_dict = dict()
        self.project_dict["植物大战僵尸-普通版"] = "zwdzjs-v1"
        self.project_dict["植物大战僵尸-外挂版"] = "zwdzjs-v2"
        self.project_dict["保卫萝卜"] = "tafang"
        self.project_dict["2048"] = "2048"
        self.project_dict["读心术"] = "dxs"

        # 调用初始化游戏项目的方法
        self.init_project()

    def init_project(self):
        # 2.1  显示所有可以发布的游戏菜单
        # 取出字典的所有key,转化为列表
        keys_list = list(self.project_dict.keys())
        # 遍历显示所有的key
        # enumerate()会为列表添加索引[(0, ), (1, ), ...]
        for index, game_name in enumerate(keys_list):
            print(index, game_name)

        # 2.2  接收用户的选择
        sel_no = int(input("请选择要发布的游戏序号:n"))

        # 2.3  保存用户选择的游戏对应的本地目录
        # 根据用户的选择,得到游戏的名称
        key_name = keys_list[sel_no]  # 列表
        current_dir = self.project_dict[key_name]
        # print(current_dir)
        self.current_dir = current_dir

    def start(self):
        print("Web服务器已经启动...等待客户端连接...")
        # 6、接受客户端连接(定义函数request_handler())
        while True:
            new_client_socket, ip_port = self.tcp_server_socket.accept()
            print('新客户来了:{}'.format(str(ip_port)))
            self.request_handler(new_client_socket, ip_port)

    def request_handler(self, new_client_socket, ip_port):
        # 接收信息,并做出响应
        # 7、新的套接字接受客户端发送的请求报文
        request_data = new_client_socket.recv(1024)
        # print(request_data)

        # 解析请求报文,返回响应报文
        response_data = app.application(new_client_socket, self.current_dir, request_data, ip_port)

        # 10、发送响应报文
        new_client_socket.send(response_data)
        new_client_socket.close()


def main():
    # 主函数

    """
    1、导入sys模块
    2、获取系统传递到程序的参数
    3、判断参数格式是否正确
    4、判断端口号是否是一个数字
    5、获取端口号
    6、在启动Web服务器的时候,使用指定的端口

    """
    # 2、获取系统传递到程序的参数
    params_list = sys.argv
    print(params_list)

    # 3、判断参数格式是否正确
    if len(params_list) != 2:
        print("启动失败:参数格式错误!正确格式:python3 xxx.py 端口号")
        return

    # 4、判断端口号是否是一个数字
    if not params_list[1].isdigit():
        print("启动失败,端口号不是一个纯数字!")
        return

    # 5、获取端口号
    port = int(params_list[1])

    # 6、在启动Web服务器的时候,使用指定的端口
    ws = WebServer(port)
    ws.start()


if __name__ == '__main__':
    main()






app.py代码

#!/usr/bin/env python
# encoding: utf-8
# @Time    : 2019/10/10 9:21 AM
# @Author  : Li Xinjian  
# @File    : app.py


from application import utils


def parse_request(new_client_socket, request_data, ip_port):
    # 返回请求的资源的路径
    # 8、判断协议是否为空
    # 如果发送的为空,说明客户端下线
    if len(request_data) == 0:
        print('{}客户端已经下线'.format(str(ip_port)))
        new_client_socket.close()
        return

    # 根据客户端浏览器请求的资源路径,返回请求资源
    # 1)把请求协议解码(直接传递过来的是二进制),得到请求报文的请求行字符串
    request_text = request_data.decode()
    # 2) 得到请求行
    #      1) 查找第一个rn出现的位置
    loc = request_text.find("rn")
    #      2) 截取字符串,从开头截取到rn出现的位置
    request_line = request_text[:loc]
    print(request_line)
    #      3) 把请求按空格分割,得到三个部分,需要的是第二个
    request_list = request_line.split(" ")
    # print(request_list)
    # 得到请求资源的路径
    file_path = request_list[1]

    # 如果直接打开,返回index.html
    if file_path == "/":
        file_path = "/index.html"

    return file_path


def application(new_client_socket, current_dir, request_data, ip_port):
    # 处理请求
    # 返回资源的路径
    file_path = parse_request(new_client_socket, request_data, ip_port)
    # 文件夹路径 + 请求的资源路径
    resource_path = current_dir + file_path

    # 响应主体
    try:
        with open(resource_path, "rb") as file:
            # 把读取的内容返回给客户端
            response_body = file.read()
        response_data = utils.create_http_response("200 OK", response_body)
    except Exception as e:
        # 如果不存在,返回提示的错误
        response_body = "Not Found. {}".format(str(e))
        response_body = response_body.encode()
        response_data = utils.create_http_response("404 Not Found", response_body)

    # response_body = "HelloWorld"

    return response_data




utils.py代码

#!/usr/bin/env python
# encoding: utf-8
# @Time    : 2019/10/10 10:18 AM
# @Author  : Li Xinjian  
# @File    : utils.py.py


def create_http_response(status, response_body):
    # 拼接报文
    # 9、拼接响应报文
    # 不为空,返回响应报文
    # 响应行
    response_line = "HTTP/1.1 {}rn".format(status)
    # 响应头
    response_head = "Server:Python20WS/2.1rn"
    response_head += "Content-Type: text/htmlrn"
    # 响应空行
    response_blank = "rn"

    response_data = (response_line + response_head + response_blank).encode() + response_body

    return response_data






运行截图

d261bbd9b875a5057d941cc195ddcc50.png
可以在客户端打开ip,完响应的游戏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值