HTTP静态WEB服务器
HTTP的作用
- 伯纳斯-李在1989年提出了万维网的基本框架,三个核心概念分别是HTTP协议、URL和HTML。HTTP协议就是浏览器和web服务器之间特定的数据传输格式。
- HTTP网络协议栈由以下几部分构成,加入安全层的即为HTTPS协议。
- 物理层:
- 数据链路层:提供网络结构
- 网络层:IP
- 传输层:TCP
- (安全层:SSL)
- 应用层:HTTP
- 与基于TCP的服务器相比,HTTP服务器特殊之处是接受和发送的内容为HTTP报文,HTTP报文由三部分构成,Start line、Header、Body。
面向对象的HTTP静态WEB服务器
import socket, sys, threading
class HttpServer(object):
'''定义一个HTTP服务器'''
def __init__(self,port):
static_web_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
static_web_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 能够通过输入制定端口
static_web_server.bind(('127.0.0.1', port))
self.static_web_server = static_web_server
def start(self):
# 启动服务器
self.static_web_server.listen(128)
while True:
client_service, client_ip_port = self.static_web_server.accept()
# 实现多线程并设置守护
sub_web_thread = threading.Thread(target=HttpServer.supply_service,
args=(client_service,), daemon=True)
sub_web_thread.start()
@staticmethod
def supply_service(client_service):
recv_data = client_service.recv(4096)
# 检查客户端提交的请求中是否存在HTTP格式中的资源路径,若无则关闭连接
try:
request_path = recv_data.decode('utf-8').split(' ', maxsplit=2)[1]
except Exception as error:
client_service.close()
return
else:
# 根目录返回index页面
if request_path == '/':
request_path = '/index.html'
# 根据资源路径制作响应报文并发送
HttpServer.make_response(request_path, client_service)
@staticmethod
def make_response(request_path,client_service):
# 检查目录下是否存在请求页面,若无返回error页面
try:
with open('static' + request_path, 'rb') as f_obj:
send_data = f_obj.read()
except Exception as error:
response_line = 'HTTP/1.1 404 Not Found\r\n'
response_header = 'Server:PWS/1.0\r\n'
with open('static/error.html', 'rb') as f_obj:
response_body = f_obj.read()
else:
# 封装成HTTP相应格式
response_line = 'HTTP/1.1 200 OK\r\n'
response_header = 'Server:PWS/1.0\r\n'
response_body = send_data
finally:
response = (response_line + response_header + '\r\n').encode('utf-8') + response_body
client_service.send(response)
client_service.close()
def main():
# 获取命令行参数,并判断是否是正确的端口号
# 判断获取的参数列表是否是两个item(第一个item是文件名),
if len(sys.argv) != 2:
print('Please enter like"python web_server 10086"')
return
# 判断获取的参数是否是有效的端口号
if sys.argv[1].isdigit():
port = int((sys.argv)[1])
if 1023 < port < 65536:
web_server = HttpServer(port)
web_server.start()
else:
print('port is invalid.')
return
else:
print('port is invalid.')
return
# 判断是否是主程序
if __name__ == '__main__':
main()
在python文件当前命令行输入python web_server 10086
,浏览器就能在http://localhost:10086/index.html中访问static文件夹下的页面。
总结
分步骤逐步开发
- 编写基于TCP的服务器
- 从请求报文中解析资源路径,并按HTTP报文格式发送响应报文
- 函数封装、类封装
- 命令行启动