05 | pythonHTTP入门
HTTP传输
HTTP协议 (超文本传输协议)
-
用途 : 网页获取,数据的传输
-
特点
- 应用层协议,传输层使用tcp传输
- 简单,灵活,很多语言都有HTTP专门接口
- 无状态,协议不记录传输内容
- http1.1 支持持久连接,丰富了请求类型
- 网页请求过程
1.客户端(浏览器)通过tcp传输,发送http请求给服务端
2.服务端接收到http请求后进行解析
3.服务端处理请求内容,组织响应内容
4.服务端将响应内容以http响应格式发送给浏览器
5.浏览器接收到响应内容,解析展示
HTTP请求(request)
- 请求行 : 具体的请求类别和请求内容
GET / HTTP/1.1
请求类别 请求内容 协议版本
请求类别:每个请求类别表示要做不同的事情
GET : 获取网络资源
POST :提交一定的信息,得到反馈
HEAD : 只获取网络资源的响应头
PUT : 更新服务器资源
DELETE : 删除服务器资源
CONNECT
TRACE : 测试
OPTIONS : 获取服务器性能信息
- 请求头:对请求的进一步解释和描述
Accept-Encoding: gzip
- 空行
- 请求体: 请求参数或者提交内容
http响应(response)
- 响应格式:响应行,响应头,空行,响应体
- 响应行 : 反馈基本的响应情况
HTTP/1.1 200 OK
版本信息 响应码 附加信息
响应码 :
1xx 提示信息,表示请求被接收
2xx 响应成功
3xx 响应需要进一步操作,重定向
4xx 客户端错误
5xx 服务器错误
- 响应头:对响应内容的描述
Content-Type: text/html
- 响应体:响应的主体内容信息
🔧 一个简单的网页服务器
"""
注意在 linux 系统下运行
IO多路复用 , http训练
"""
from socket import *
from select import select
# 具体功能服务
class HTTPServer:
def __init__(self, host='0.0.0.0', port=80, dir=None):
self.host = host
self.port = port
self.dir = dir
self.address = (host, port)
# select 的监控列表
self.rlist = []
self.wlist = []
self.xlist = []
# 直接创建出套接字
self.create_socket()
self.bind()
# 创建套接字
def create_socket(self):
self.sockfd = socket()
self.sockfd.setsockopt(SOL_SOCKET,
SO_REUSEADDR, 1)
# 绑定
def bind(self):
self.sockfd.bind(self.address)
# 启动入口
def serve_forever(self):
self.sockfd.listen(3)
print("Listen the port %d" % self.port)
# 搭建IO多路服用监控各种IO请求
self.rlist.append(self.sockfd)
while True:
rs, wx, xs = select(self.rlist,
self.wlist,
self.xlist)
for r in rs:
# 浏览器连接进来
if r is self.sockfd:
c, addr = r.accept()
self.rlist.append(c)
else:
# 处理客户端请求
self.handle(r)
# 处理客户端请求
def handle(self, connfd):
# 接收http请求
request = connfd.recv(4096)
# 客户端断开
if not request:
self.rlist.remove(connfd)
connfd.close()
return
# 提起请求内容 ---(将字节串按行切割)得到请求行---
request_line = request.splitlines()[0]
info = request_line.decode().split(' ')[1]
print(connfd.getpeername(), '请求内容:', info)
# 根据请求内容进行数据整理
# 分为两类: 1. 请求网页,2. 其他
if info == '/' or info[-5:] == '.html':
self.get_html(connfd, info)
else:
self.get_data(connfd, info)
# 处理网页
def get_html(self, connfd, info):
if info == '/':
# 请求主页
filename = self.dir + '/index.html'
else:
filename = self.dir + info
try:
fd = open(filename)
except Exception:
# 网页不存在
response = "HTTP/1.1 404 Not Found\r\n"
response += "Content-Type:text/html\r\n"
response += '\r\n'
response += "<h1>Sorry....</h1>"
else:
response = "HTTP/1.1 200 OK\r\n"
response += "Content-Type:text/html\r\n"
response += '\r\n'
response += fd.read()
finally:
# 讲内容发送给浏览器
connfd.send(response.encode())
# 处理其他
def get_data(self, connfd, info):
f = open(self.dir + "/timg.jpg", 'rb')
data = f.read()
response = "HTTP/1.1 200 OK\r\n"
response += "Content-Type:image/jpeg\r\n"
response += '\r\n'
response = response.encode() + data
connfd.send(response)
# 用户应该怎么用HTTPServer
if __name__ == '__main__':
"""
通过HTTPServer快速启动服务,用于展示自己的网页
"""
# 需要用户自己决定的内容
HOST = '0.0.0.0'
PORT = 8000
DIR = "./static" # 网页存储位置
httpd = HTTPServer(HOST, PORT, DIR)
httpd.serve_forever() # 服务启动入口