08-Python实现网游服务器
目标¶
- 能够利用Web服务器选择发布Web项目
1. 功能分析¶
1、用户使用浏览器打开指定地址
2、游戏运行方启动服务器,选择要发布的游戏
3、客户端刷新浏览器即可畅玩新的游戏
2. 实现思路¶
1、定义初始化项目的方法
2、定义字典保存项目路径 字典格式:key=项目名称 value=路径
3、循环获取字典中的所有key
4、根据key获取游戏的主目录
5、设置实例属性,保存主目录
6、修改Web服务器的目录为实例属性保存的主目录
3. 核心代码¶
dict()
可以用来创建一个空字典
projects_dict = dict() #定义一个空字典 projects_dict
projects_dict.key()
返回值是一个含有字典所有keydick_keys
的对象,可以的通过list(projects_dict.key())
得到一个列表
keys_list = list(self.projects_dict.keys())
enumerate(keys_list)
会把列表组合为一个索引序列
my_list = ['Spring', 'Summer', 'Fall', 'Winter']
list2 = enumerate(my_list) # 将my_list组合成索引序列
print(list2) 结果如下:
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
Content-Type: text/html
服务器响应头中加入这句话,表示浏览器优先使用html解析服务器返回的内容
4. 代码实现¶
import socket
from application import app
import sys
class WebServer(object):
"""WebServer-Web服务器类"""
# 定义初始化方法
def __init__(self, port):
# 1、创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2、设置套接字属性(地址可以重用)
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 3、绑定端口(8080)
tcp_server_socket.bind(("", port))
# 4、开启监听,设置套接字由主动设置为被动
tcp_server_socket.listen(128)
# 保存socket 到实例属性中
self.tcp_server_socket = tcp_server_socket
# 初始化项目
self.projects_dict = dict()
# 初始化当前项目路径
self.current_dir = ""
# 初始化字典值
self.projects_dict['植物大战僵尸-普通版'] = "zwdzjs-v1"
self.projects_dict['植物大战僵尸-外挂版'] = "zwdzjs-v2"
self.projects_dict['保卫萝卜'] = "tafang"
self.projects_dict['2048'] = "2048"
self.projects_dict['读心术'] = "dxs"
# 初始化菜单
self.init_projects()
def init_projects(self):
# 1、获取字典所有的key
dict_keys = tuple(self.projects_dict.keys())
# print(dict_keys)
# 2、输出提示信息
print("请选择要发布的项目:\n")
# 3、循环输出项目列表
for index, value in enumerate(dict_keys):
print("%d.%s" % (index, value))
# 4、接受用户输入的编号
sel_num = int(input("请选择要发布的游戏编号:\n"))
# 5、根据编号得到字典key
sel_key = dict_keys[sel_num]
print("已经成功发布游戏[%s],客户端请刷新网页使用!" % sel_key)
# 6、根据字典key获取当前发布的项目的目录
# 7、保存项目目录到实例变量中
self.current_dir = self.projects_dict[sel_key]
# 定义启动服务器方法
def start(self):
while True:
# 5、接受客户端连接并拆包
new_client_socket, ip_port = self.tcp_server_socket.accept()
# 6、调用 request_handler() 处理请求
self.request_handler(new_client_socket, ip_port)
# 定义响应服务器方法
def request_handler(self, new_client_socket, ip_port):
"""接受客户端请求并处理"""
# 1、接受客户端请求报文
request_data = new_client_socket.recv(1024)
# 2、判断客户端是否已经下线
if not request_data:
print("客户端[%s]已经下线~" % str(ip_port))
new_client_socket.close()
return
# 调用 app 模块的 application 方法处理请求
response_data = app.application(self.current_dir, request_data)
# 4、发送请求报文
new_client_socket.send(response_data)
# 5、关闭连接
new_client_socket.close()
def main():
# 判断参数个数是否合法
if len(sys.argv) != 2:
print("启动失败,参数个数错误!正确格式:python xxx.py 8080")
return
# 判断端口是否是纯数字
if not sys.argv[1].isdigit():
print("启动失败,端口不是数字!")
return
# 保存端口
port = int(sys.argv[1])
"""主入口方法"""
# 1、创建对象
ws = WebServer(port)
# 2、启动服务器
ws.start()
if __name__ == '__main__':
main()