• python socket 制作http服务器 (面向对象封装)


    目录

     一、面向对象封装

    二、给服务器加上命令行参数

    三、植物大战僵尸小游戏服务器 


     一、面向对象封装

            在上一篇博客(使用 python socket 向http服务器发送请求并制作http服务器
    基础上进行面向对象封装。

    代码:

    1. import socket
    2. from threading import Thread
    3. class WebServer(object):
    4. # 初始化方法
    5. def __init__(self):
    6. # 创建套接字
    7. self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    8. # 设置地址重用 SOL_SOCKET表示当前套接字,SO_REUSEADDR表示设置地址重用
    9. self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    10. # 绑定端口
    11. self.tcp_server_socket.bind(("", 8080))
    12. # 设置监听,让套接字由主动变为被动接收
    13. self.tcp_server_socket.listen(128)
    14. def start(self):
    15. """ 启动Web服务器 """
    16. while True:
    17. # 接收客户端连接 定义函数
    18. new_client_socket, ip_port = self.tcp_server_socket.accept()
    19. print("新的客户端%s已连接!" % str(ip_port))
    20. # 接收请求并作出响应
    21. t1 = Thread(target=self.request_handler, args=(new_client_socket, ip_port))
    22. t1.start()
    23. def request_handler(self, new_client_socket, ip_port):
    24. """接收信息,并且做出响应"""
    25. # 接收客户端浏览器发送的请求协议
    26. request_data = new_client_socket.recv(1024) # 接收请求报文
    27. # print(request_data)
    28. # 判断协议是否为空
    29. if not request_data:
    30. print("%s客户端已下线!" % str(ip_port))
    31. new_client_socket.close()
    32. else:
    33. # 根据客户端浏览器请求的资源路径,返回请求资源
    34. # 1.把请求协议解码,得到请求报文的字符串
    35. request_text = request_data.decode()
    36. # 2.得到请求行
    37. # 2.1 查找 第一个\r\n出现的位置
    38. loc = request_text.find("\r\n")
    39. # 2.2 截取字符串,从开头截取到 第一个\r\n出现的位置
    40. request_line = request_text[:loc]
    41. # print(request_line)
    42. # 2.3 把请求行按照空格拆分,得到列表
    43. request_line_list = request_line.split(" ")
    44. # 2.4 得到请求资源路径
    45. file_path = request_line_list[1]
    46. print("%s 正在请求:%s" % (str(ip_port), file_path))
    47. # 响应行
    48. response_line = "HTTP/1.1 200 OK\r\n"
    49. # 响应头
    50. response_header = "Server:Python20WS/2.1\r\n"
    51. # 响应空行
    52. response_blank = "\r\n"
    53. # 响应主体
    54. # 返回字符串内容
    55. # response_body = "Hello World"
    56. # 返回固定页面
    57. try:
    58. with open("static" + file_path, "rb") as file:
    59. response_body = file.read()
    60. except Exception as e:
    61. # 重新修改响应行为 404
    62. response_line = "HTTP/1.1 404 Not Found\r\n"
    63. response_body = "Error! %s " % str(e)
    64. response_body = response_body.encode()
    65. # 拼接响应报文
    66. response_data = (response_line + response_header + response_blank).encode() + response_body
    67. # 发送响应报文
    68. new_client_socket.send((response_data))
    69. # 关闭连接
    70. new_client_socket.close()
    71. if __name__ == '__main__':
    72. WS = WebServer()
    73. WS.start()

    二、给服务器加上命令行参数

    1. import socket,sys
    2. from threading import Thread
    3. class WebServer(object):
    4. # 初始化方法
    5. def __init__(self, port):
    6. # 创建套接字
    7. self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    8. # 设置地址重用 SOL_SOCKET表示当前套接字,SO_REUSEADDR表示设置地址重用
    9. self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    10. # 绑定端口
    11. self.tcp_server_socket.bind(("", port))
    12. # 设置监听,让套接字由主动变为被动接收
    13. self.tcp_server_socket.listen(128)
    14. def start(self):
    15. """ 启动Web服务器 """
    16. while True:
    17. # 接收客户端连接 定义函数
    18. new_client_socket, ip_port = self.tcp_server_socket.accept()
    19. print("新的客户端%s已连接!" % str(ip_port))
    20. # 接收请求并作出响应
    21. t1 = Thread(target=self.request_handler, args=(new_client_socket, ip_port))
    22. t1.start()
    23. def request_handler(self, new_client_socket, ip_port):
    24. """接收信息,并且做出响应"""
    25. # 接收客户端浏览器发送的请求协议
    26. request_data = new_client_socket.recv(1024) # 接收请求报文
    27. # print(request_data)
    28. # 判断协议是否为空
    29. if not request_data:
    30. print("%s客户端已下线!" % str(ip_port))
    31. new_client_socket.close()
    32. else:
    33. # 根据客户端浏览器请求的资源路径,返回请求资源
    34. # 1.把请求协议解码,得到请求报文的字符串
    35. request_text = request_data.decode()
    36. # 2.得到请求行
    37. # 2.1 查找 第一个\r\n出现的位置
    38. loc = request_text.find("\r\n")
    39. # 2.2 截取字符串,从开头截取到 第一个\r\n出现的位置
    40. request_line = request_text[:loc]
    41. # print(request_line)
    42. # 2.3 把请求行按照空格拆分,得到列表
    43. request_line_list = request_line.split(" ")
    44. # 2.4 得到请求资源路径
    45. file_path = request_line_list[1]
    46. print("%s 正在请求:%s" % (str(ip_port), file_path))
    47. # 响应行
    48. response_line = "HTTP/1.1 200 OK\r\n"
    49. # 响应头
    50. response_header = "Server:Python20WS/2.1\r\n"
    51. # 响应空行
    52. response_blank = "\r\n"
    53. # 响应主体
    54. # 返回字符串内容
    55. # response_body = "Hello World"
    56. # 返回固定页面
    57. try:
    58. with open("static" + file_path, "rb") as file:
    59. response_body = file.read()
    60. except Exception as e:
    61. # 重新修改响应行为 404
    62. response_line = "HTTP/1.1 404 Not Found\r\n"
    63. response_body = "Error! %s " % str(e)
    64. response_body = response_body.encode()
    65. # 拼接响应报文
    66. response_data = (response_line + response_header + response_blank).encode() + response_body
    67. # 发送响应报文
    68. new_client_socket.send((response_data))
    69. # 关闭连接
    70. new_client_socket.close()
    71. def main():
    72. # 获取系统传递到程序的参数
    73. params_list = sys.argv
    74. # print(params_list)
    75. # 判断参数个数
    76. if len(params_list) != 2:
    77. print("启动失败,正确启动格式:python xxx.py port")
    78. # 判断端口号是否为纯数字
    79. if not params_list[1].isdigit():
    80. print("启动失败,端口号应为纯数字")
    81. port = int(params_list[1])
    82. WS = WebServer(port)
    83. WS.start()
    84. if __name__ == '__main__':
    85. main()

    结果:

     

     

    三、植物大战僵尸小游戏服务器 

    项目结构:

     

     服务端代码:

    1. import socket,sys
    2. class WebServer(object):
    3. # 初始化方法
    4. def __init__(self, port):
    5. # 创建套接字
    6. self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    7. # 设置地址重用 SOL_SOCKET表示当前套接字,SO_REUSEADDR表示设置地址重用
    8. self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    9. # 绑定端口
    10. self.tcp_server_socket.bind(("", port))
    11. # 设置监听,让套接字由主动变为被动接收
    12. self.tcp_server_socket.listen(128)
    13. self.project_dict = {}
    14. self.project_dict["足球大战僵尸"] = "h5-game-footballVSzombies"
    15. self.project_dict["植物大战僵尸"] = "h5-game-plantsVSzombies"
    16. self.current_dir = ""
    17. self.init_projects()
    18. def init_projects(self):
    19. # 显示所有的游戏名称
    20. key_list = list(self.project_dict.keys()) # 取出字典的key并且转换成列表
    21. for index, gameName in enumerate(key_list):
    22. print("%d.%s" % (index, gameName))
    23. # 接收用户的选择
    24. sel_no = int(input("请选择游戏序号:\n"))
    25. # 根据用户的选择来运行指定游戏
    26. key = key_list[sel_no]
    27. # 根据key得到项目路径
    28. self.current_dir = self.project_dict[key]
    29. print(key, self.current_dir)
    30. def start(self):
    31. """ 启动Web服务器 """
    32. print("网游服务器已启动!")
    33. while True:
    34. # 接收客户端连接 定义函数
    35. new_client_socket, ip_port = self.tcp_server_socket.accept()
    36. print("新的客户端%s已连接!" % str(ip_port))
    37. # 接收请求并作出响应
    38. self.request_handler(new_client_socket, ip_port)
    39. def request_handler(self, new_client_socket, ip_port):
    40. """接收信息,并且做出响应"""
    41. # 接收客户端浏览器发送的请求协议
    42. request_data = new_client_socket.recv(1024) # 接收请求报文
    43. # print(request_data)
    44. # 判断协议是否为空
    45. if not request_data:
    46. print("%s客户端已下线!" % str(ip_port))
    47. new_client_socket.close()
    48. else:
    49. # 根据客户端浏览器请求的资源路径,返回请求资源
    50. # 1.把请求协议解码,得到请求报文的字符串
    51. request_text = request_data.decode()
    52. # 2.得到请求行
    53. # 2.1 查找 第一个\r\n出现的位置
    54. loc = request_text.find("\r\n")
    55. # 2.2 截取字符串,从开头截取到 第一个\r\n出现的位置
    56. request_line = request_text[:loc]
    57. # print(request_line)
    58. # 2.3 把请求行按照空格拆分,得到列表
    59. request_line_list = request_line.split(" ")
    60. # 2.4 得到请求资源路径
    61. file_path = request_line_list[1]
    62. print("%s 正在请求:%s" % (str(ip_port), file_path))
    63. if file_path == "/":
    64. file_path = "/index.html"
    65. # 响应行
    66. response_line = "HTTP/1.1 200 OK\r\n"
    67. # 响应头
    68. response_header = "Server:Python20WS/2.1\r\n"
    69. # response_header = response_header + "Content-Type: text/html\r\n"
    70. # 响应空行
    71. response_blank = "\r\n"
    72. # 响应主体
    73. # 返回字符串内容
    74. # response_body = "Hello World"
    75. # 返回固定页面
    76. try:
    77. with open(self.current_dir + file_path, "rb") as file:
    78. response_body = file.read()
    79. except Exception as e:
    80. # 重新修改响应行为 404
    81. response_line = "HTTP/1.1 404 Not Found\r\n"
    82. response_body = "Error! %s " % str(e)
    83. response_body = response_body.encode()
    84. # 拼接响应报文
    85. response_data = (response_line + response_header + response_blank).encode() + response_body
    86. # 发送响应报文
    87. new_client_socket.send((response_data))
    88. # 关闭连接
    89. new_client_socket.close()
    90. def main():
    91. # 获取系统传递到程序的参数
    92. params_list = sys.argv
    93. # print(params_list)
    94. # 判断参数个数
    95. if len(params_list) != 2:
    96. print("启动失败,正确启动格式:python xxx.py port")
    97. # 判断端口号是否为纯数字
    98. if not params_list[1].isdigit():
    99. print("启动失败,端口号应为纯数字")
    100. port = int(params_list[1])
    101. WS = WebServer(port)
    102. WS.start()
    103. if __name__ == '__main__':
    104. main()

    效果:

     

     前端代码下载地址:

    原生JS实现的h5小游戏-植物大战僵尸

  • 相关阅读:
    Java学习之super关键字
    c语言难点
    使用【时间差】调整时间datetime.timedelta()
    【BLE】蓝牙抓包器 Ellisys 使用说明
    WebGPU的计算着色器实现冒泡排序
    Java NIO ByteBuffer原理使用图文详解
    Rust vs C++ 深度比较
    青少年python系列 42.面向对象-继承
    支持CAN FD的Kvaser PCIEcan 4xCAN v2编码: 73-30130-01414-5如何应用?
    初中级前端程序员面试中小型公司会问哪些问题
  • 原文地址:https://blog.csdn.net/ChaoChao66666/article/details/126798296