导入sys模块
import socket
import threading
import sys
# 定义web服务器类
class HttpWebServer(object):
def __init__(self, port):
# 创建服务端套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置端口号复用, 程序退出,端口号立即释放
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定端口号
tcp_server_socket.bind(('', port))
# 设置监听
tcp_server_socket.listen(128)
self.tcp_server_socket = tcp_server_socket
@staticmethod
# 处理客户端请求
def handle_client_request(new_socket):
# 接收数据
recv_data = new_socket.recv(4096)
# 判断客户端是否发送数据
if len(recv_data) == 0:
print('客户端断开连接了')
# 关闭服务于客户端的套接字
new_socket.close()
return
# 对二进制数据进行解码
recv_content = recv_data.decode('utf-8')
print(recv_content)
# 以空格进行分割
request_list = recv_content.split(' ', 2)
# 对请求数据切片获取路径
request_path = request_list[1]
print(request_path)
# 判断返回的是否是根目录,如果是则返回首页数据
if request_path == '/':
request_path = '/index.html'
try:
# 打开发送内容,此时是以'rb'方式打开,打开内容为二进制
with open('static' + request_path, 'rb') as file:
# 读取内容
file_data = file.read()
except Exception as e:
# 请求资源不存在,返回404数据
# 响应行
response_line = 'HTTP/1.1 404 NOT FOUND\r\n'
# 响应头
response_header = 'Server: PWS/1.1\r\n'
# 打开发送内容,此时是以'rb'方式打开,打开内容为二进制
with open('static/error.html', 'rb') as file:
# 读取内容
file_data = file.read()
# 响应体,此时的响应体是二进制
response_body = file_data
# 将数据封装成http响应报文格式
response = (response_line +
response_header +
'\r\n').encode('utf-8') + response_body
# 发送响应报文数据
new_socket.send(response)
else:
# 响应行
response_line = 'HTTP/1.1 200 OK\r\n'
# 响应头
response_header = 'Server: PWS/1.1\r\n'
# 响应体,此时的响应体是二进制
response_body = file_data
# 将数据封装成http响应报文格式
response = (response_line +
response_header +
'\r\n').encode('utf-8') + response_body
# 发送响应报文数据
new_socket.send(response)
finally:
# 关闭服务于客户端的套接字
new_socket.close()
# 定义启动web服务器进行工作的方法
def start(self):
# 循环等待接受客户端的连接请求
while True:
# 等待接受客户端的连接请求
new_socket, ip_port = self.tcp_server_socket.accept()
# 创建子线程
sub_thread = threading.Thread(target=self.handle_client_request, args=(new_socket,))
# 设置守护主线程,主线程退出,子线程直接销毁
sub_thread.setDaemon(True)
sub_thread.start()
# 程序入口
def main():
# 获取终端命令行参数
params = sys.argv
if len(params) != 2 or not params[1].isdigit():
print('参数不符合要求')
return
# 获取终端命令行参数
port = int(params[1])
# 创建web服务器对象
web_server = HttpWebServer(port)
# 启动web服务器进行工作
web_server.start()
if __name__ == '__main__':
main()