web框架的进阶实现——函数线程传文件版
普通方法实现
文件一模一样,我们用函数的方式实现每一步:
# -*- coding:utf-8 -*-
import socket
def index(conn):
with open('index.html','rb')as f:
data = f.read()
conn.sendall(data)
conn.close()
def ico(conn):
with open('favicon.ico','rb')as f:
data = f.read()
conn.sendall(data)
conn.close()
def img(conn):
with open('1.jpg','rb')as f:
data = f.read()
conn.sendall(data)
conn.close()
if __name__ == '__main__':
# 处理的函数列表
opt_lst = [
('/',index),
('/favicon.ico',ico),
('/1.jpg',img),
]
# 初始化socket
server = socket.socket()
#设置端口重复利用
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind(('127.0.0.1',8899))
server.listen()
while 1:
conn,addr = server.accept()
msg = conn.recv(65105).decode('utf-8')
# print(msg)
#获取path
path = msg.split('\r\n\r\n')[0].split()[1]
# 先发送响应的协议
conn.sendall(b'HTTP/1.1 200 OK \r\n\r\n')
#根据不同的路径调用相应的函数
for i in opt_lst:
if path == i[0]:
i[1](conn)
多线程实现文件的并发上传
可以专门为每个传文件的函数开多线程提高效率。
代码如下:
# -*- coding:utf-8 -*-
import socket
from threading import Thread
def index(conn):
with open('index.html','rb')as f:
data = f.read()
conn.sendall(data)
conn.close()
def ico(conn):
with open('favicon.ico','rb')as f:
data = f.read()
conn.sendall(data)
conn.close()
def img(conn):
with open('1.jpg','rb')as f:
data = f.read()
conn.sendall(data)
conn.close()
def handle(opt_lst,path,conn):
for i in opt_lst:
if path == i[0]:
# 开线程传文件
t = Thread(target=i[1],args=(conn,))
t.start()
if __name__ == '__main__':
# 处理的函数列表
opt_lst = [
('/', index),
('/favicon.ico', ico),
('/1.jpg', img),
]
# 初始化socket
server = socket.socket()
#设置端口重复利用
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind(('127.0.0.1',8765))
server.listen()
#连接循环
while 1:
conn,addr = server.accept()
msg = conn.recv(65105).decode('utf-8')
# print(msg)
path = msg.split('\r\n\r\n')[0].split()[1]
print(path)
# 先法响应协议
conn.sendall(b'HTTP/1.1 200 OK \r\n\r\n')
# 执行handle函数
handle(opt_lst,path,conn)
我们在浏览器中输入127.0.0.1:8765就可以看到效果了。
上面的代码实现了“多线程上传文件”,结合前一篇博客的“多线程接收请求”,两者结合可以这样写:
# -*- coding:utf-8 -*-
import socket
from threading import Thread
def run_server(conn,opt_lst):
msg = conn.recv(65105).decode('utf-8')
# print(msg)
path = msg.split('\r\n\r\n')[0].split()[1]
print(path)
# 先发响应协议
conn.sendall(b'HTTP/1.1 200 OK \r\n\r\n')
# 开多线程执行文件操作
t = Thread(target=handle,args=(opt_lst,path,conn))
t.start()
def index(conn):
with open('index.html','rb')as f:
data = f.read()
conn.sendall(data)
conn.close()
def ico(conn):
with open('favicon.ico','rb')as f:
data = f.read()
conn.sendall(data)
conn.close()
def img(conn):
with open('1.jpg','rb')as f:
data = f.read()
conn.sendall(data)
conn.close()
def handle(opt_lst,path,conn):
for i in opt_lst:
if path == i[0]:
i[1](conn)
if __name__ == '__main__':
# 处理的函数列表
opt_lst = [
('/', index),
('/favicon.ico', ico),
('/1.jpg', img),
]
# 初始化socket
server = socket.socket()
#设置端口重复利用
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind(('127.0.0.1',8765))
server.listen()
#连接循环
while 1:
conn,addr = server.accept()
# 开线程处理连接
t = Thread(target=run_server, args=(conn,opt_lst))
t.start()
上面代码说明了单线程下也可以开线程但是考虑到数据共享问题上面的实现方式不安全!