要求
实现文件上传下载 ,多并发,比如能演示出两个链接同时下载文件
实现功能:
能实现多客户端下载,但没有再写上传功能
selectors_server.py:
import selectors
import socket
import hashlib,file_operation
class accept_class(object):
def __init__(self):
self.conn = None
self.addr = None
self.mask = None
def accept(self,sock, mask):
conn, addr = sock.accept()
self.conn = conn
self.addr = addr
self.mask = mask
print('accepted', self.conn, 'from', self.addr)
self.conn.setblocking(False)
read1 = read_class()
sel.register(self.conn, selectors.EVENT_READ, read1.read)
class read_class(object):
def __init__(self):
self.conn = None
self.mask = None
self.satue = 0
self.cmd =None
self.recv_size = 0
self.total_size = 0
self.f = None
self.md = 0
self.pbar = 0
self.file_op = None
def read(self,conn,mask):
data = conn.recv(1024) # Should be ready
if data:
#接收命令
if self.satue == 0:
cmd_data = data.decode()
print(cmd_data)
cmd_dict = cmd_data.split()
if cmd_dict[0] == 'up':
self.cmd = 'up'
if cmd_dict[0] == 'download':
self.cmd = 'download'
self.satue = 1
conn.send(b'ok')#
#接收数据长度
elif self.satue == 1:
real_data = data.decode()
print("***********Down Start***********")
print('down:',real_data )
file_total_size = int(real_data)
print('down file_total_size:',file_total_size)
self.total_size = file_total_size
self.f = open('filename' + 'new','wb')
self.m = hashlib.md5()
self.pbar = file_operation.Progressbar()
self.file_op = file_operation.DownLoadfile()
self.satue = 2
#接收数据
elif self.satue == 2:
#print('recv data:',data.strip().decode())
if self.recv_size != self.total_size:
self.file_op.down_sel(data,self.recv_size,self.total_size,self.f,self.m,self.pbar)
self.recv_size += len(data)
else:
new_file_md5 = self.m.hexdigest()
server_datamd5 = data.decode()
print("file recv done",self.recv_size,self.total_size)
print("down_md5:",new_file_md5)
print('up_md5:',server_datamd5)
self.satue == 3
print("***********Down Done***********")
self.satue = 0
self.cmd =None
self.recv_size = 0
self.total_size = 0
self.f = None
self.md = 0
self.pbar = 0
self.file_op = None
else:
pass
else:
print('closing', conn)
sel.unregister(conn)
conn.close()
sock = socket.socket()
sock.bind(('localhost', 9999))
sock.listen(100)
sock.setblocking(False)
sel = selectors.DefaultSelector()
accept1 = accept_class()
sel.register(sock, selectors.EVENT_READ, accept1.accept)
includes = {}
while True:
events = sel.select()
for key, mask in events:
callback = key.data
callback(key.fileobj, mask)
selectors_client.py:
import socket
import file_operation
class Ftpclient_start(object):
def __init__(self):
pass
def start(self):
client.connect((HOST,PORT))
while True:
try:
msg = input(">>>:")
except:
break
else:
client.send(msg.encode()) # send cmd to the server
if msg.startswith('up'): # "up data.txt"
file_operation.Upfile.up(client,msg.split()[1],'client')
elif msg.startswith('download'):
file_operation.DownLoadfile.down(client,msg.split()[1],'client')
if __name__ == "__main__":
client = socket.socket()
HOST,PORT = "localhost",9999
client_start = Ftpclient_start()
client_start.start()
file_operation.py
import hashlib,os,socket,time
class Upfile(object):
"""
Upfile(filename)
"""
def __init__(self):
pass
def up(self,*args):
print("***********Up Start***********")
if os.path.isfile(args[0]):
f = open(args[0],'rb')
m = hashlib.md5()
filesize = os.stat(args[0]).st_size
print('up filesize:',filesize)
ack = self.recv(1024)
self.send(str(filesize).encode(encoding='utf-8'))
time.sleep(0.1)
for line in f:
m.update(line)#.encode(encoding='utf-8')
self.send(line)#.encode(encoding='utf-8')
#print("send line:",line)
print('up file md5:',m.hexdigest())
f.close()
time.sleep(0.1)
self.send(m.hexdigest().encode(encoding='utf-8'))#
print("***********Up Done***********")
class DownLoadfile(object):
"""
DownLoadfile(filepath)
"""
def __init__(self):
pass
def down(self,*args):
print("***********Down Start***********")
print('down:',args )
self.send(b'ok')#
file_total_size = int(self.recv(1024).strip().decode())
print('down file_total_size:',file_total_size)
recv_size = 0
filename = args[0]#[0][1]
print('filename:',filename)
f = open(filename + 'new','wb')
m = hashlib.md5()
pbar = Progressbar()
while recv_size != file_total_size:
if file_total_size - recv_size > 1024:
size = 1024
else:
size = file_total_size - recv_size
data = self.recv(size)
recv_size += len(data)
m.update(data)
f.write(data)
f.flush()
#print('recv_size:',recv_size,'file_total_size:',file_total_size)
print("Processing:%.2f%%" %(pbar.progressing(recv_size, file_total_size)))
else:
new_file_md5 = m.hexdigest()
server_datamd5 = self.recv(1024).decode()
print("file recv done",recv_size,file_total_size)
print("down_md5:",new_file_md5)
print('up_md5:',server_datamd5)
print("***********Down Done***********")
def down_sel(self,data,recv_size,file_total_size,f,m,pbar):
recv_size += len(data)
m.update(data)
f.write(data)
f.flush()
#print('recv_size:',recv_size,'file_total_size:',file_total_size)
print("Processing:%.2f%%" %(pbar.progressing(recv_size, file_total_size)))
class Progressbar(object):
def __init__(self):
pass
def progressing(self,temp,total):
return temp/total*100
class Discretetrainsport(object):
"""
Discretetrainsport(filepath,continue_point)
"""
def __init__(self):
pass
def discrete(self,*args):
print(*args)
class Account_homepage(object):
def __init__(self,file):
self.file_path = file
def getrealpath(self):
rp = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '\\home\\' + self.file_path
return rp
def addpath(self,file):
self.file_path = self.file_path + '\\' + file
return self.file_path
def decpath(self):
path_list = self.file_path.split('\\')
self.file_path = '\\'.join(path_list[0:-1])
return self.file_path
#def ls(self,send):
def ls(self):
print(os.listdir(self.getrealpath()))
#send.request.sendall(str(os.listdir(self.getrealpath())).encode(encoding='utf-8'))
return os.listdir(self.getrealpath())
def cd(self,*args):
base_path = self.getrealpath() + "\\"
path_len = len(self.file_path.split('\\'))
if not args[0] == "../":
if os.path.isdir(base_path+args[0]):
self.file_path = self.addpath(args[0])
print("new path:",self.file_path)
return self.file_path
else:
print(" ********* ",args[0]," doesn't exist.."," ********* ")
return (" ********* ",args[0]," doesn't exist.."," ********* ")
#return False
elif args[0] == "../" and path_len > 1:
self.file_path = self.decpath()
print("new path:",self.file_path)
return self.file_path
else:
print(" ********* You have got into the bottom ********* ")
return(" ********* You have got into the bottom ********* ")
#return False
def creat(self,*args):
pass
if __name__ == "__main__":
a1 = Account_homepage("hcl\home\ln")
a1.addpath('1234')
a1.decpath()
输出:
server端输出:
accepted <socket.socket fd=524, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 53636)> from ('127.0.0.1', 53636)
up love.txt
***********Down Start***********
down: 2216
down file_total_size: 2216
Processing:4.69%
Processing:30.42%
Processing:34.07%
Processing:39.35%
Processing:42.64%
Processing:47.20%
Processing:48.60%
Processing:51.99%
Processing:56.05%
Processing:58.75%
Processing:63.04%
Processing:65.39%
Processing:68.05%
Processing:69.18%
Processing:76.90%
Processing:77.66%
Processing:81.23%
Processing:84.75%
Processing:90.75%
Processing:95.80%
Processing:97.83%
Processing:100.00%
file recv done 2216 2216
down_md5: c1f2393c7bea1f00b35180ab8ddad95c
up_md5: c1f2393c7bea1f00b35180ab8ddad95c
***********Down Done***********
up love.txt
***********Down Start***********
down: 2216
down file_total_size: 2216
Processing:1.71%
Processing:6.68%
Processing:10.33%
Processing:16.38%
Processing:20.17%
Processing:26.62%
Processing:30.42%
Processing:32.94%
Processing:35.65%
Processing:39.35%
Processing:42.64%
Processing:44.77%
Processing:48.60%
Processing:51.99%
Processing:56.05%
Processing:58.75%
Processing:63.67%
Processing:66.74%
Processing:69.18%
Processing:76.90%
Processing:79.56%
Processing:83.89%
Processing:84.75%
Processing:90.75%
Processing:95.80%
Processing:97.83%
Processing:100.00%
file recv done 2216 2216
down_md5: c1f2393c7bea1f00b35180ab8ddad95c
up_md5: c1f2393c7bea1f00b35180ab8ddad95c
***********Down Done***********
accepted <socket.socket fd=544, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 53637)> from ('127.0.0.1', 53637)
up love12.txt
***********Down Start***********
down: 9
down file_total_size: 9
Processing:100.00%
file recv done 9 9
down_md5: f5bb0c8de146c67b44babbf4e6584cc0
up_md5: f5bb0c8de146c67b44babbf4e6584cc0
***********Down Done***********
up love.txt
***********Down Start***********
down: 2216
down file_total_size: 2216
Processing:3.16%
Processing:10.33%
Processing:16.38%
Processing:17.06%
Processing:23.65%
Processing:29.96%
Processing:34.07%
Processing:37.41%
Processing:40.70%
Processing:42.64%
Processing:47.20%
Processing:48.60%
Processing:51.99%
Processing:54.38%
Processing:56.05%
Processing:58.75%
Processing:60.97%
Processing:63.04%
Processing:63.67%
Processing:66.74%
Processing:68.05%
Processing:69.18%
Processing:72.83%
Processing:77.66%
Processing:79.56%
Processing:84.75%
Processing:93.68%
Processing:97.83%
Processing:100.00%
file recv done 2216 2216
down_md5: c1f2393c7bea1f00b35180ab8ddad95c
up_md5: c1f2393c7bea1f00b35180ab8ddad95c
***********Down Done***********
client客户端1输出:
>>>:up love.txt
***********Up Start***********
up filesize: 2216
up file md5: c1f2393c7bea1f00b35180ab8ddad95c
***********Up Done***********
>>>:up love.txt
***********Up Start***********
up filesize: 2216
up file md5: c1f2393c7bea1f00b35180ab8ddad95c
***********Up Done***********
>>>:
client客户端2输出:
>>>:up love12.txt
***********Up Start***********
up filesize: 9
up file md5: f5bb0c8de146c67b44babbf4e6584cc0
***********Up Done***********
>>>:up love.txt
***********Up Start***********
up filesize: 2216
up file md5: c1f2393c7bea1f00b35180ab8ddad95c
***********Up Done***********
>>>:
六、有兴趣接电子设计相关小型项目的请加下群,每个项目一般在1000元以内,非诚勿扰