本文共 5252 字,大约阅读时间需要 17 分钟。
浏览器实际上就是一个socket客户端
网络上所有的交互都是基于socket连接Web应用(网站)
浏览器(socket客户端)【这个chrom、IE都帮我们写好了】 2. 访问https://www.csdn.net(47.95.164.112:80) sk.socket() sk.connnect(47.95.164.112:80) sk.send("我想要xx") 5. 接收 6. 自己断开CSDN(socket服务端)【这个是程序员写的部分】 1. 监听自己的ip和端口(47.95.164.112:80) while True: 用户 = 等待用户连接 3. 收到“我想要xx” 4. 响应:“好,给你xx” 用户断开
import socket #创建socket服务端sock = socket.socket() #创建一个socket对象sock.bind('127.0.0.1',9000) #把一个ipv4或ipv6地址和端口号组合赋给socketsock.listen(5) #最多等5个请求while True: conn,addr = sock.accept() #hang住,进行阻塞住 等待 # 有人来连接了 # 获取用户发送数据 data = conn.recv(8096) #浏览器给服务器发送数据(采用HTTP协议) data = str(data,encoding='utf-8') #将data转换为字符串 headers,bodys = data.split('\r\n\r\n') #进行分割请求头和请求体 temp_list = headers.split('\r\n') #将请求头继续分割 method,url,protocal = temp_list[0].split(' ') #将第一行再按照空格分割,为请求方法、url、协议 conn.send(b"HTTP/1.1 200 OK\r\n\r\n") #浏览器返回响应头 if url == "/xxx": #如果用户请求的界面是/xxx,则服务器返回123123 conn.send(b'123123') #服务器回发数据(响应体) else: conn.send(b'404 not found') conn.close() #关闭连接这样写的缺点没有模块化,需要写大量的url请求路径,特别复杂
首先我们先进行模块化处理
import socket #创建socket服务端def run(): sock = socket.socket() #创建一个socket对象 sock.bind('127.0.0.1',9000) #把一个ipv4或ipv6地址和端口号组合赋给socket sock.listen(5) #最多等5个请求 while True: conn,addr = sock.accept() #hang住,进行阻塞住 等待 # 有人来连接了 # 获取用户发送数据 data = conn.recv(8096) #浏览器给服务器发送数据(采用HTTP协议) data = str(data,encoding='utf-8') #将data转换为字符串 headers,bodys = data.split('\r\n\r\n') #进行分割请求头和请求体 temp_list = headers.split('\r\n') #将请求头继续分割 method,url,protocal = temp_list[0].split(' ') #将第一行再按照空格分割,为请求方法、url、协议 conn.send(b"HTTP/1.1 200 OK\r\n\r\n") #浏览器返回响应头 if url == "/xxx": #如果用户请求的界面是/xxx,则服务器返回123123 conn.send(b'123123') #服务器回发数据(响应体) else: conn.send(b'404 not found') conn.close() #关闭连接if __name__ == "__main__": run() #一旦启动这个脚本就会运行run函数
然后解决URL之间的关系,并对应放在不同的函数里面
此时的网站已经搭建好了,但是是一个静态的网站,里面的数据是不变化的 (没有从数据库中拿取数据)Document 用户登录
然后构动态网站,将html充当一个模板,模板里面放置特殊的占位符,然后通过数据库动态替换,
也就是虽然CSDN这个界面的格式排版没有变化,但是里面的数据展示内容经常发生变化,说明不断的更新,从数据库中取出新的数据,最终将这个拿到的数据嵌入HTML页面import socket #创建socket服务端import pymysqldef f1(request): """ 函数的目标: 处理用户的请求,并返回相应的内容 request:用户请求的所有信息 """ f = open('index.html','rb') #把html页面返回给用户,本质返回的是一大堆字符串 data = f.read() f.close() return datadef f2(request): return b'f2'def f3(request): #1.连接数据库 conn = pymysql.connect(host="127.0.0.1",post=3306, user='root',passwd="root",db="student") #2.进行数据库查询语句操作 cursor = conn.cursor(cursor=pymysql.cursor.DictCursor) cursor.execute("select id,usernaem,password from userinfo") user_list = cursor.fetchall() #返回值是多个元组,即返回多个行记录,如果没有结果,返回的是0 cursor.close() conn.close() # 获取user_list的数据格式 """ [ {id,username,password} {id,username,password} {id,username,password} ] """ # 对数据库获取到的数据进行包装 content_list = [] for row in user_list: tp = "%s%s%s" %(row['id'],row['username'],row['password']) content_list.append(tp) #将上面一大堆的字符串拼接到一起 content = "".join(content_list) # 获取页面展示的模板 f = open('userlist.html','rb') #把html页面返回给用户,本质返回的是一大堆字符串 temlate = f.read() f.close() # 将上述拼接到一起的字符串替换模板里面特殊标记字符,并将结果返回给客户端页面 # 又叫模板的渲染(模板+数据) data = temlate.replace("@asdfsfsa@",content) return bytes(data,encoding="utf-8") #此时客户端页面就可以以列表形式动态的展示数据库里面的数据routers = [ #处理url,进行列表存储url和函数之间关系的映射 ('/xxx',f1), ('/ooo',f2), ('/userlist.html',f3)]def run(): sock = socket.socket() #创建一个socket对象 sock.bind('127.0.0.1',9000) #把一个ipv4或ipv6地址和端口号组合赋给socket sock.listen(5) #最多等5个请求 while True: conn,addr = sock.accept() #hang住,进行阻塞住 等待 # 有人来连接了 # 获取用户发送数据 data = conn.recv(8096) #浏览器给服务器发送数据(采用HTTP协议) data = str(data,encoding='utf-8') #将data转换为字符串 headers,bodys = data.split('\r\n\r\n') #进行分割请求头和请求体 temp_list = headers.split('\r\n') #将请求头继续分割 method,url,protocal = temp_list[0].split(' ') #将第一行再按照空格分割,为请求方法、url、协议 conn.send(b"HTTP/1.1 200 OK\r\n\r\n") #浏览器返回响应头 func_name = None for item in routers: #取出每一个url if item[0] == url: #如果用户输入的url和服务器中存储的某一个url相等 func_name = item[1] #获取服务器中这个url对应的函数名 break if func_name: #如果存在这个函数名 response = func_name(data) #调用这个函数,参数data包含请求头和请求体 else: response = b"404" conn.send(response) #服务器把得到的结果返回给用户 conn.close() #关闭连接if __name__ == "__main__": run() #一旦启动这个脚本就会运行run函数
模板渲染我们可使用别人写好的工具库(第三方工具),例如jinja2
http是无状态+短连接
TCP是不断开
浏览器给服务器发送的数据头
服务端发送数据给客户端,客户端响应服务器的信息头
Status Code: 200 OK
响应体就是web界面的HTML代码 就是用户从页面从页面上看到的内容就是响应体。(本质是“字符串”,只是被浏览解析为HTML代码了)我们自己写网站的要求
写的是socket服务端
根据用户输入URL的不同,返回不同的内容
我们写一个路由系统,表示的是URL和函数的对应关系本质都是字符串返回给用户
动态页面就是把HTML充当模板 自己创造任意数据 HTML模板里面包含特殊字符 模板引擎渲染:(本质是字符串的替换) 然后将结果返回给用户
框架种类:
Tornado
Django属于第二类
没有自己的socket服务端 使用的是python的内置模块:wsgiref——>Django进行处理flask
分类二
转载地址:http://oqxzi.baihongyu.com/