1.HTTP协议
用途: 网页获取,数据的传输
特点:
-
-
简单,灵活,很多语言都有HTTP专门接口
-
无状态,数据传输过程中不记录传输内容
-
有丰富了请求类型
-
网页访问流程
客户端(浏览器)通过TCP传输,发送http请求给服务端
服务端接收到http请求后进行解析
服务端处理请求内容,组织响应内容
服务端将响应内容以http响应格式发送给浏览器
浏览器接收到响应内容,解析展示
HTTP请求
请求行:具体的请求类别和请求内容
GET / HTTP/1.1 请求类别 请求内容 协议版本
请求类别:每个请求类别表示要做不同的事情
GET : 获取网络资源
POST :提交一定的信息,得到反馈
HEAD : 只获取网络资源的响应头
PUT : 更新服务器资源
DELETE : 删除服务器资源
请求头:对请求的进一步解释和描述
Accept-Encoding: gzip
空行
请求体:请求参数或者提交内容
HTTP响应
响应行:反馈基本的响应情况
HTTP/1.1 200 OK 版本信息 响应码 附加信息
响应码:
1xx 提示信息,表示请求被接收
2xx 响应成功
3xx 响应需要进一步操作,重定向
4xx 客户端错误
5xx 服务器错误
响应头:对响应内容的描述
Content-Type: text/html Content-Length:109
空行
响应体:响应的主体内容信息
练习:
【2】 解析客户端发送的请求
【3】 根据请求组织数据内容
【4】 将数据内容形成http响应格式返回给浏览器
特点 :
【1】 采用IO并发,可以满足多个客户端同时发起请求情况
【2】 通过类接口形式进行功能封装
""" web server 程序 完成一个类,提供给使用者 可以通过这个类快速搭建服务 完成网页展示 """ from socket import * from select import select import re # 封装所有web后端功能 class WebServer: def __init__(self, host="0.0.0.0", port=80, html=None): self.host = host self.port = port self.html = html self.rlist = [] self.wlist = [] self.xlist = [] self.create_socket() self.bind() # 创建设置套接字 def create_socket(self): self.sock = socket() self.sock.setblocking(False) # 绑定地址 def bind(self): self.address = (self.host, self.port) self.sock.bind(self.address) # 启动整个服务 def start(self): self.sock.listen(5) print("Listen the port %d" % self.port) # 先监控监听套接字 self.rlist.append(self.sock) # 循环监控IO对象 while True: rs, ws, xs = select(self.rlist, self.wlist, self.xlist) # 处理就绪的IO for r in rs: # 有客户端连接 if r is self.sock: connfd, addr = r.accept() print("Connect from", addr) # 将客户端连接套接字也监控起来 connfd.setblocking(False) self.rlist.append(connfd) else: # 处理浏览器端发的请求 try: self.handle(r) except: pass self.rlist.remove(r) r.close() # 处理客户端请求 def handle(self, connfd): # http请求 request = connfd.recv(1024 * 10).decode() # 使用正则匹配请求内容 pattern = r"[A-Z]+s+(?P<info>/S*)" result = re.match(pattern, request) if request: # 提取请求内容 info = result.group("info") print("请求内容:",info) self.send_html(connfd,info) # 发送响应 def send_html(self,connfd,info): # 对info分情况 if info == "/": filename = self.html + "/index.html" else: filename = self.html + info # 打开判断文件是否存在 try: file = open(filename,"rb") except: # 请求的网页不存在 response = "HTTP/1.1 404 Not Found " response += "Content-Type:text/html " response += " " with open(self.html+"/404.html") as file: response += file.read() response = response.encode() else: # 请求的网页存在 data = file.read() # 字节串 response = "HTTP/1.1 200 OK " response += "Content-Type:text/html " response += "Content-Length:%d "%len(data) response += " " response = response.encode() + data file.close() finally: connfd.send(response) if __name__ == '__main__': # 需要用户决定: 地址 网页 httpd = WebServer(host="0.0.0.0", port=8000, html="./static") # 启动服务 httpd.start()