目录
1.c/s架构
2.b/s架构
3.基于socket写一个web应用
main.py
index.html
4.手写web框架
main.py
login.html
time.html
user_list.html
user_list_new
二.HTTP协议
1.什么是HTTP协议
2.HTTP协议的作用
3.HTTP版本及区别
4.HTTP协议的特点
5.HTTP请求协议
常用的请求头:
6.HTTP响应协议
常见的HTTP状态码:
c/s:客户端 ---> 服务端(MySQL是客户端和服务端在同一台机器上)
优点:
- 客户端和服务端直接相连
- 客户端可以处理一些逻辑事务
- 客户端操作界面
缺点:
- 客户端:
只能处理一些功能单一的多系统
适用于局域网,对网速要求高
安装部署困难,不易扩展- 服务器:
用户数增多会出现通信拥堵
对服务器的要求很高- 用户:
没安装客户端的外部用户不能访问
用户数受限,不易扩张
b/s:浏览器--->服务端
优点:
- 能面向广大的用户实现信息传播共享
- 浏览器负担小
- 页面的更新能实时同步
- 软件重用性强,节省大量成本
缺点:
- 客户端:
页面需要不停的动态刷新,网速慢的情况很费时间
面对大量不可知用户- 服务器:
用户增多,服务器响应慢
不能处理复杂功能*****b/s架构本质上就是c/s架构*****
import socket
def server_run():
soc = socket.socket()
soc.bind(('127.0.0.1', 8008))
soc.listen(5)
while True:
conn, addr = soc.accept()
recv_data = conn.recv(1024)
print(recv_data)
# 1 直接在send里写,发送给客户端
# conn.send(b'HTTP/1.1 200 OK\r\n\r\nhello web
')
#2 打开一个html文件,发送给客户端
# with open('index.html','r',encoding='utf-8') as f:
# data=f.read()
# conn.send(('HTTP/1.1 200 OK\r\n\r\n%s'%data).encode('utf-8'))
# 3 动态网页,字符串替换
import time
now=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
print(now)
with open('index.html','r',encoding='utf-8') as f:
data=f.read()
data=data.replace('@@@',now)
conn.send(('HTTP/1.1 200 OK\r\n\r\n%s'%data).encode('utf-8'))
conn.close()
if __name__ == '__main__':
server_run()
Title
@@@
import socket
import pymysql
def index(request):
return ''
def login(request):
with open('login.html','r',encoding='utf-8') as f :
data=f.read()
return data
def time(request):
import datetime
now=datetime.datetime.now().strftime('%Y-%m-%d %X')
with open('time.html','r',encoding='utf-8') as f :
data=f.read()
data=data.replace('@@time@@',now)
return data
def user_list(request):
# 创建连接
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='lqz')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute("select id,name,password from user")
user_list = cursor.fetchall()
cursor.close()
conn.close()
tr_list=[]
for row in user_list:
tr='%s %s %s '%(row['id'],row['name'],row['password'])
tr_list.append(tr)
with open('user_list.html','r',encoding='utf-8') as f:
data=f.read()
data=data.replace('@@body@@',''.join(tr_list))
return data
def user_list_new(request):
# 创建连接
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='lqz')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
cursor.execute("select id,name,password from user")
user_list = cursor.fetchall()
cursor.close()
conn.close()
with open('user_list_new.html','r',encoding='utf-8') as f:
data=f.read()
from jinja2 import Template
template=Template(data)
response=template.render(user_list=user_list)
# response=template.render({'user_list':user_list})
return response
urls = [
('/index', index),
('/login', login),
('/time', time),
('/user_list', user_list),
('/user_list_new', user_list_new),
]
def run():
soc = socket.socket()
soc.bind(('127.0.0.1', 8006))
soc.listen(5)
while True:
conn, port = soc.accept()
data = conn.recv(1024)
# data=data.decode('utf-8')
print(data)
data = str(data, encoding='utf-8')
request_list = data.split('\r\n\r\n')
head_list = request_list[0].split('\r\n')
method, url, htt = head_list[0].split(' ')
# conn.send(b'hello web')
conn.send(b'HTTP/1.1 200 OK \r\n\r\n')
print(url)
func_name = None
for u in urls:
if url == u[0]:
func_name = u[1]
break
if func_name:
response = func_name(data)
else:
response = '404 not found'
conn.send(response.encode('utf-8'))
conn.close()
if __name__ == '__main__':
run()
Title
Title
@@time@@
用户列表
id
用户名
密码
@@body@@
用户列表
id
name
password
{% for user in user_list%}
{{user.id}}
{{user.name}}
{{user.password}}
{%endfor%}
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)
服务器与本地浏览器之间传输超文本的传送协议
0.9:功能捡漏,只支持GET方法,只能发送HTML格式字符串。
1.1:默认持久连接、请求管道化、增加缓存处理、增加Host字段、支持断点传输分块传输等。
2.0:二进制分帧、多路复用、头部压缩、服务器推送
3.0:弃用TCP,改用基于UDP协议的QUIC协议代替TCP协议。
- 支持客户端/服务端模式
- 简单快速:客户端向服务端发送请求时,只需要传送请求方式和路径(GET、POST、HEAD)
- 灵活:HTTP允许传输任意类型的数据对象,正在传输的类型由Content-Type加以标记
- 无连接:限制每次连接只处理一个请求,服务器处理完客户请求并接收到客户的响应后即断开连接
- 无状态:协议对于事务处理没有记忆能力,缺少状态意味着如果后续处理需要前面的信息则必须重传,这样可能导致每次连接传送的数据量增大,另一方面,在服务器不需要先前信息时响应就很快
一个HTTP请求报文(也称请求消息)由请求行(request line)、请求头(header)、空行和请求数据(也称请求体)4个部分组成
请求行
请求头1
请求头2
……
请求空行
请求体
请求行:由请求字段、URL字段和HTTP协议版本字段三部分组成,用空格分隔
请求行格式:Method空格Request-URL空格HTTP-Version \r\n
Method:表示请求方法
Request-URL:表示一个统一资源标识符
HTTP-Version:表示请求的HTTP协议版本
\r\n:表示换行
- Content-Type: 数据类型(text/html等)。
- Content-Length: 请求体Body的长度。
- User-Agent:产生请求的浏览器类型。
- Accept:客户端希望接收的响应数据类型。就是希望服务器返回什么类型的数据。
- Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机。
- referer: 当前页面是从哪个页面跳转过来的。
- location: 搭配3xx状态码使用,告诉客户端接下来要去哪里访问。
- Cookie: 用于在客户端存储少量信息,通常用于实现会话(session)的功能。
HTTP响应也由三个部分组成,分别是:状态行、响应头、空行、响应正文
状态行
响应头1
响应头2
……
响应空行
响应体
状态行:由 协议版本,状态码,[状态码说明] 三部分组成
状态行格式:HTTP-Version空格Status-Code空格Reason-Phrase
HTTP-Version表示服务器HTTP协议的版本,例如为HTTP/1.1
Status-Code表示服务器发回的响应状态代码,例如200
Reason-Phrase表示状态代码的文本描述
- 1xx:指示信息--表示服务器收到请求,需要请求者继续执行操作。
- 2xx:成功--表示操作被成功接收并处理。
- 3xx:重定向--需要进一步的操作以完成请求。
- 4xx:客户端错误--请求有语法错误或请求无法完成。
- 5xx:服务器端错误--服务器在处理请求的过程中发生了错误。