Python--select版的FTP
1、要求
用select模块实现FTP上传文件和下载文件的功能
2、目录
3、实现,主要修改的还是server的代码
client端
1 import socket 2 import os 3 from lib import * 4 5 def download(): 6 msg = 'download ' 7 #显示要下载的目录中的文件 8 filename=input('输入你要下载的文件名(保存到当前路径)') 9 msg +=filename 10 return msg 11 12 def upload(): 13 msg='upload ' 14 filedir=input("输入你要上传的文件路径") 15 filename=filedir.split('\\')[-1] 16 msg += filename+' ' 17 with open(filedir,'r') as fd: 18 msg +=fd.read() 19 return msg 20 21 def bye(): 22 msg='exit' 23 return msg 24 25 def showfile(): 26 msg='currentfiles' 27 client.send(msg.encode('utf-8')) 28 reply=client.recv(1024).decode('utf-8') 29 print(reply) 30 print("您可以从download目录下载需要的文件,保存在当前工作目录,或上传文件至upload目录。") 31 return 32 33 def storefile(): 34 filename = input("请输入要保存的名字:") 35 filepath = os.path.join(os.getcwd(), filename) 36 with open(filepath, 'w') as fd: 37 fd.write(reply) 38 return 39 40 client=socket.socket() 41 client.connect(('localhost',21)) 42 ftprequest={'1':download,'2':upload,'3':bye} 43 44 while True: 45 showfile() 46 incmd = input("你要干嘛?\n1、下载文件\n2、上传文件\n3、退出") 47 if incmd in ftprequest.keys(): 48 mess=ftprequest[incmd]() 49 client.send(mess.encode('utf-8')) 50 if mess=='exit': 51 break 52 reply = client.recv(1024).decode('utf-8') 53 if incmd=='1': 54 storefile() 55 client.close()
server端
1 import socket 2 import os 3 import select 4 import queue 5 from lib import * 6 7 def showfiles(): 8 curdir = pathdefine.downloaddir 9 returnstr = '' 10 for root, dirs, files in os.walk(curdir): 11 returnstr += 'rootdir:' + root + '\n' 12 for d in dirs: 13 returnstr += 'directory:' + d + '\n' 14 for f in files: 15 returnstr += 'file:' + f + '\n' 16 print(returnstr) 17 conn.send(returnstr.encode('utf-8')) 18 return 19 20 #建立服务器socket、绑定、监听 21 server=socket.socket() 22 server.bind(('127.0.0.1',21)) 23 server.listen(100) 24 server.setblocking(False) 25 26 inputs = [server, ] #自己也要监测呀,因为server本身也是个fd 27 outputs = [] 28 29 message_queues = {} 30 31 while True: 32 print("waiting for next event...") 33 34 readable, writeable, exeptional = select.select(inputs,outputs,inputs) #如果没有任何fd就绪,那程序就会一直阻塞在这里 35 36 for s in readable: #每个s就是一个socket 37 38 if s is server: 39 conn, client_addr = s.accept() 40 print("new connection from",client_addr) 41 conn.setblocking(False) 42 inputs.append(conn) 43 else: 44 data = s.recv(1024) 45 if data: 46 datastr=data.decode('utf-8') 47 if datastr=='exit': 48 if s in outputs: 49 outputs.remove(s) 50 inputs.remove(s) 51 del message_queues[s] 52 elif datastr == 'currentfiles': 53 showfiles() 54 elif datastr.startswith('download'): 55 strlist = datastr.split() 56 filename = strlist[1] 57 dirname = os.path.join(pathdefine.downloaddir, filename) 58 with open(dirname, 'r') as fd: 59 msg = fd.read() 60 conn.send(msg.encode('utf-8')) 61 elif datastr.startswith('upload'): 62 strlist = datastr.split() 63 filename = strlist[1] 64 filecont = strlist[2] 65 dir = os.path.join(pathdefine.uploaddir, filename) 66 with open(dir, 'w') as fd: 67 fd.write(filecont) 68 conn.send(b'***') 69 else:#如果收不到data代表什么呢? 代表客户端断开了呀 70 print("客户端断开了",s) 71 if s in outputs: 72 outputs.remove(s) #清理已断开的连接 73 inputs.remove(s) #清理已断开的连接 74 for s in exeptional: 75 print("handling exception for ",s.getpeername()) 76 inputs.remove(s) 77 if s in outputs: 78 outputs.remove(s) 79 s.close()