zoukankan      html  css  js  c++  java
  • 01-静态web服务器(Python)-面向对象的对比

    普通写法,静态web服务器:

    • 先创建TCP服务器套接字,然后等待客户端(这里是浏览器)请求连接。
    • 客户端发起请求,用线程来处理连接的建立,这样可以实现多任务(也就是并发)
    • 连接后根据请求发送指定页面

    补充:设置守护主线程:当主线程退出,子线程立马全死

      1 import socket
      2 import os
      3 import threading
      4 
      5 # 处理客户端的请求
      6 def handle_client_request(new_socket):
      7     # 代码执行到此,说明连接建立成功
      8     # 连接客户端的请求信息
      9     recv_data = new_socket.recv(4096)
     10     # 判断接收到的数据长度是否为0
     11     if len(recv_data) == 0:  # 用来解决客户端一连接服务器就关闭的现象
     12         new_socket.close()
     13         return
     14 
     15     # 对二进制数据进行解码
     16     recv_content = recv_data.decode("UTF-8")
     17     print(recv_data)
     18 
     19     # 对数据按照空格进行分割(maxsplit=2表示分割两次,得到3个。其格式为元组)
     20     request_list = recv_content.split(" ", maxsplit=2)
     21     # 获取请求的资源路径
     22     request_path = request_list[1]
     23     print(request_path)
     24 
     25     # 判断请求的是否是根目录,如果是根目录设置返回的信息
     26     if request_path == "/":
     27         request_path = "/index.html"
     28 
     29     # 判断该路径的文件是否存在,有两种方法
     30     # 方法一:os.path.exists
     31     # os.path.exists("static/" + request_path)
     32     # 方法二:try-except异常抛出的4件套
     33 
     34     try:
     35         # 打开文件读取文件中的数据,提示:这里使用rb模式,兼容打开图片文件(用二进制的方式)
     36         with open("static" + request_path, "rb") as file:  # 这里的file表示打开文件的对象
     37             file_data = file.read()
     38         # 提示:with open  关闭文件这步操作不用程序来完成,系统帮我们完成
     39 
     40     except Exception as e:
     41         # 代码执行到此,说明没有请求的该文件,返回404状态信息
     42         # 响应行
     43         response_line = "HTTP/1.1 404 Not Found
    "
     44         # 响应头
     45         response_header = "Server:PWS/1.0
    "
     46         # 空行
     47 
     48         # 读取404页面数据
     49         with open("static/error.html", "rb") as file:
     50             file_data = file.read()
     51         # 响应体
     52         response_body = file_data
     53 
     54         # 把数据封装成http,响应报文格式的数据
     55         response = (response_line +
     56                     response_header +
     57                     "
    ").encode("UTF-8") + response_body
     58 
     59         # 发送给浏览器的响应报文数据
     60         new_socket.send(response)
     61 
     62     else:
     63         # 代码执行到此,说明文件存在,返回200状态信息
     64         # 响应行
     65         response_line = "HTTP/1.1 200 OK
    "
     66         # 响应头
     67         response_header = "Server: pws/1.0
    "
     68         # 空行
     69         # 响应体
     70         response_body = file_data
     71 
     72         # 把数据封装成http,响应报文格式的数据
     73         response = (response_line +
     74                     response_header +
     75                     "
    ").encode("UTF-8") + response_body  # 响应行/头是字符串,响应体是二进制。
     76         # 这里把响应行/头也改成二进制,再连接起来
     77         # 发送给浏览器的响应报文数据
     78         new_socket.send(response)
     79 
     80     finally:
     81         # 关闭服务于客户端的套接字
     82         new_socket.close()
     83 
     84 
     85 def main():
     86     # 创建TCP服务器套接字
     87     tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     88     # 设置端口号复用,程序退出端口号立即释放
     89     tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
     90     # 绑定端口号
     91     tcp_server_socket.bind(("", 8000))
     92     # 设置监听
     93     tcp_server_socket.listen(128)
     94     # 循环等待接受客户端的连接请求
     95     while True:
     96         # 等待接受客户端的连接请求
     97         new_socket, ip_port = tcp_server_socket.accept()
     98         # 当客户端和服务器建立连接,创建子线程
     99         sub_thread = threading.Thread(target=handle_client_request, args=(new_socket,))
    100         # 设置守护主线程
    101         sub_thread.setDaemon(True)
    102         # 启动子线程执行的对应任务
    103         sub_thread.start()
    104 
    105 
    106 if __name__ == '__main__':
    107     main()

    面向对象的写法:

    • 用类进行封装,
    • TCP服务器套接字直接写在__init__里面,这样默认就会创建
      1 import socket
      2 import os
      3 import threading
      4 
      5 
      6 # Http协议的web服务器类
      7 class HttpWebServer(object):
      8     def __init__(self):
      9         # 创建TCP服务器套接字
     10         tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     11         # 设置端口号复用,程序退出端口号立即释放
     12         tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
     13         # 绑定端口号
     14         tcp_server_socket.bind(("", 8000))
     15         # 设置监听
     16         tcp_server_socket.listen(128)
     17         # 把TCP服务器的套接字做为web服务器对象的属性
     18         self.tcp_server_socket = tcp_server_socket
     19 
     20     # 处理客户端请求
     21     @staticmethod
     22     def handle_client_request(new_socket):
     23         # 代码执行到此,说明连接建立成功
     24         # 连接客户端的请求信息
     25         recv_data = new_socket.recv(4096)
     26         # 判断接收到的数据长度是否为0
     27         if len(recv_data) == 0:  # 用来解决客户端一连接服务器就关闭的现象
     28             new_socket.close()
     29             return
     30 
     31         # 对二进制数据进行解码
     32         recv_content = recv_data.decode("UTF-8")
     33         print(recv_data)
     34 
     35         # 对数据按照空格进行分割(maxsplit=2表示分割两次,得到3个。其格式为元组)
     36         request_list = recv_content.split(" ", maxsplit=2)
     37         # 获取请求的资源路径
     38         request_path = request_list[1]
     39         print(request_path)
     40 
     41         # 判断请求的是否是根目录,如果是根目录设置返回的信息
     42         if request_path == "/":
     43             request_path = "/index.html"
     44 
     45         # 判断该路径的文件是否存在,有两种方法
     46         # 方法一:os.path.exists
     47         # os.path.exists("static/" + request_path)
     48         # 方法二:try-except异常抛出的4件套
     49 
     50         try:
     51             # 打开文件读取文件中的数据,提示:这里使用rb模式,兼容打开图片文件(用二进制的方式)
     52             with open("static" + request_path, "rb") as file:  # 这里的file表示打开文件的对象
     53                 file_data = file.read()
     54             # 提示:with open  关闭文件这步操作不用程序来完成,系统帮我们完成
     55 
     56         except Exception as e:
     57             # 代码执行到此,说明没有请求的该文件,返回404状态信息
     58             # 响应行
     59             response_line = "HTTP/1.1 404 Not Found
    "
     60             # 响应头
     61             response_header = "Server:PWS/1.0
    "
     62             # 空行
     63 
     64             # 读取404页面数据
     65             with open("static/error.html", "rb") as file:
     66                 file_data = file.read()
     67             # 响应体
     68             response_body = file_data
     69 
     70             # 把数据封装成http,响应报文格式的数据
     71             response = (response_line +
     72                         response_header +
     73                         "
    ").encode("UTF-8") + response_body
     74 
     75             # 发送给浏览器的响应报文数据
     76             new_socket.send(response)
     77 
     78         else:
     79             # 代码执行到此,说明文件存在,返回200状态信息
     80             # 响应行
     81             response_line = "HTTP/1.1 200 OK
    "
     82             # 响应头
     83             response_header = "Server: pws/1.0
    "
     84             # 空行
     85             # 响应体
     86             response_body = file_data
     87 
     88             # 把数据封装成http,响应报文格式的数据
     89             response = (response_line +
     90                         response_header +
     91                         "
    ").encode("UTF-8") + response_body  # 响应行/头是字符串,响应体是二进制。
     92             # 这里把响应行/头也改成二进制,再连接起来
     93             # 发送给浏览器的响应报文数据
     94             new_socket.send(response)
     95 
     96         finally:
     97             # 关闭服务于客户端的套接字
     98             new_socket.close()
     99 
    100     # 启动服务器的方法
    101     def start(self):
    102         # 循环等待接受客户端的连接请求
    103         while True:
    104             # 等待接受客户端的连接请求
    105             new_socket, ip_port = self.tcp_server_socket.accept()
    106             # 当客户端和服务器建立连接,创建子线程
    107             sub_thread = threading.Thread(target=self.handle_client_request, args=(new_socket,))
    108             # 设置守护主线程
    109             sub_thread.setDaemon(True)
    110             # 启动子线程执行的对应任务
    111             sub_thread.start()
    112 
    113 def main():
    114     # 创建web服务器
    115     web_server = HttpWebServer()
    116     # 启动服务器
    117     web_server.start()
    118 
    119 if __name__ == '__main__':
    120     main()
    Linux学习笔记
  • 相关阅读:
    TestNG
    K近邻算法
    Python解决乱码问题
    Log4J 配置
    多线程死锁
    hadooplzo安装出错的解决方法
    B树
    设计模式
    整数序列化
    Maven
  • 原文地址:https://www.cnblogs.com/zealwang/p/13476550.html
Copyright © 2011-2022 走看看