普通写法,静态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\r\n"
44 # 响应头
45 response_header = "Server:PWS/1.0\r\n"
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 "\r\n").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\r\n"
66 # 响应头
67 response_header = "Server: pws/1.0\r\n"
68 # 空行
69 # 响应体
70 response_body = file_data
71
72 # 把数据封装成http,响应报文格式的数据
73 response = (response_line +
74 response_header +
75 "\r\n").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\r\n"
60 # 响应头
61 response_header = "Server:PWS/1.0\r\n"
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 "\r\n").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\r\n"
82 # 响应头
83 response_header = "Server: pws/1.0\r\n"
84 # 空行
85 # 响应体
86 response_body = file_data
87
88 # 把数据封装成http,响应报文格式的数据
89 response = (response_line +
90 response_header +
91 "\r\n").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()

01-静态web服务器(Python)-面向对象的对比的更多相关文章

  1. Python之HTTP静态Web服务器开发

    众所周知,Http协议是基于Tcp协议的基础上产生的浏览器到服务器的通信协议 ,其根本原理也是通过socket进行通信. 使用HTTP协议通信,需要注意其返回的响应报文格式不能有任何问题. 响应报文, ...

  2. python网络-静态Web服务器案例(29)

    一.静态Web服务器案例代码static_web_server.py # coding:utf-8 # 导入socket模块 import socket # 导入正则表达式模块 import re # ...

  3. 04-HTTP协议和静态Web服务器

    一.HTTP协议(HyperText Transfer Protocol)     超文本传输协议,超文本是超级文本的缩写,是指超越文本限制或者超链接,比如:图片.音乐.视频.超链接等等都属于超文本. ...

  4. Harp – 内置常用预处理器的静态 Web 服务器

    Harp 是一个基于 Node.js 平台的静态 Web 服务器,内置流行的预处理器,支持把 Jade, Markdown, EJS, Less, Stylus, Sass, and CoffeeSc ...

  5. 超简易静态Web服务器

    使用 HttpListener 写的一个超简易静态Web服务器 开发环境:VS2010 + .NET2.0 http://files.cnblogs.com/zjfree/EasyIIS.rar

  6. Fenix – 基于 Node.js 的桌面静态 Web 服务器

    Fenix 是一个提供给开发人员使用的简单的桌面静态 Web 服务器,基于 Node.js 开发.您可以同时在上面运行任意数量的项目,特别适合前端开发人员使用. 您可以通过免费的 Node.js 控制 ...

  7. 用HTTP核心模块配置一个静态Web服务器

    静态Web服务器的主要功能由ngx_http_core_module模块(HTTP框架的主要成员)实现与core模块类似,可以根据相关模块(如ngx_http_gzip_filter_module.n ...

  8. node 创建静态web服务器(下)(处理异步获取数据的两种方式)

    接上一章. 上一章我们说创建的静态web服务器只能识别html,css,js文件,功能较为单一,且图片格式为text/html,这是不合理的. 本章,我们将解决该问题. 这里,我们先准备好一个json ...

  9. node 创建静态web服务器(上)

    声明:本文仅用来做学习记录. 本文将使用node创建一个简单的静态web服务器. 准备工作: 首先,准备好一个类似图片中这样的页面 第一步: 创建 http 服务: const http = requ ...

随机推荐

  1. Ubuntu下跑通py-faster-rcnn、详解demo运作流程

    在不同的服务器不同的机器上做过很多次实验,分别遇到各种不一样的错误并且跑通Py-Faster-RCNN,因此,在这里做一个流程的汇总: 一.下载文件: 首先,文件的下载可以有两种途径: 1.需要在官网 ...

  2. mybatis(二)全局配置mybatis-config.xml

    转载:https://www.cnblogs.com/wuzhenzhao/p/11092526.html 大部分时候,我们都是在Spring 里面去集成MyBatis.因为Spring 对MyBat ...

  3. Java中Class.forName()用法和newInstance()方法详解

    1.Class.forName()主要功能 Class.forName(xxx.xx.xx)返回的是一个类, Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,也就 ...

  4. 实现 MyBatis 流式查询的方法

    基本概念流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果.流式查询的好处是能够降低内存使用.如果没有流式查询,我们想要从数据库取 1000 万条记录而又没有足 ...

  5. Qt开发Activex笔记(二):Qt调用Qt开发的Activex控件

    若该文为原创文章,转载请注明原文出处本文章博客地址:https://blog.csdn.net/qq21497936/article/details/113789693 长期持续带来更多项目与技术分享 ...

  6. Web Share API

    Web Share API https://w3c.github.io/web-share/ Web Share API, W3C Editor's Draft 15 April 2020 https ...

  7. django学习-22.admi管理后台页面的文案展示等相关配置

    目录结果 1.前言 2.完整的操作步骤 2.1.第一步:对[settings.py]里的相关常量的值做如下修改 2.2.第二步:重启django项目[helloworld]的服务 2.3.第三步:重新 ...

  8. ROS 安装完成后运行小乌龟示例程序

    安装ROS成功后,在Beginner Tutorials中有一个简单的示例程序. 在Terminal中运行以下命令: $ roscore 新开一个terminal,运行以下命令,打开小乌龟窗口: $ ...

  9. HTML+CSS+JS速查手册下载

    下载链接:https://files.cnblogs.com/files/waterr/HTML_CSS_JS%E9%80%9F%E6%9F%A5.zip

  10. 26_ mysql数据操作语言:DELETE语句

    -- DELETE语句 -- 删除10部门中,工龄超过20年的员工记录 DELETE FROM t_emp WHERE deptno=10 AND DATEDIFF(NOW(),hiredate)/3 ...