select版ftp
5. **本次作业实现的需求:**
1. 使用SELECT或SELECTORS模块实现并发简单版FTP
2. 允许多用户并发上传下载文件
6. **测试:**
----------
仅支持上传下载文件
----------
7. **备注:**
1.程序运行在bin/startclient.py和startserver.py,请先运行server端,在运行client端
2.模拟的本地目录为db/client/目录,下面有两个测试文件a,b
3.模拟的服务器用户家目录为db/server目录
4.当client段或者server端强制退出时,另一端会报错。。
server端
#!/usr/bin/env python # coding=utf-8 #Author:yang import select import socket import queue,json,os from conf import settings def run(): server = socket.socket() server.bind(('localhost',9999)) server.listen(1000) server.setblocking(0) msg_dic = {} inputs = [server,] outputs = [] while True: readable ,writeable,exceptional= select.select(inputs, outputs, inputs ) for r in readable: if r is server: conn,addr = r.accept() conn.setblocking(0) inputs.append(conn) msg_dic[conn] = queue.Queue() else: data = r.recv(1024) if data: msg_dic[r].put(data) if r not in outputs: outputs.append(r) else: if r in outputs: outputs.remove(r) inputs.remove(r) del msg_dic[r] for w in writeable: try: cmd = msg_dic[w].get_nowait() except queue.Empty: outputs.remove(w) else: data = json.loads(cmd.decode()) if data['action'] == 'put': filesize = data['size'] filename = data['filename'] file = os.path.join(settings.SERVER_HOME,filename) f = open(file, "wb") received_size = 0 while received_size < filesize: data = w.recv(4096) f.write(data) received_size += len(data) else: print('文件下载完毕!') f.close() elif data['action'] == 'get': filename = data['filename'] file = os.path.join(settings.SERVER_HOME,filename) print(file) if os.path.exists(file): filesize = os.stat(file).st_size w.send(str(filesize).encode('utf-8')) f = open(file, "rb") for line in f: w.send(line) else: print("接收成功") f.close() else: w.sendall('no'.encode('utf-8')) for e in exceptional: inputs.remove(e) if e in outputs: outputs.remove(e) e.close() del msg_dic[e]
client端
#!/usr/bin/env python # coding=utf-8 #Author:yang import socket import json import os from conf import settings def run(): ftp_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) ftp_client.connect(('localhost',8008)) while True: cmd = input("(仅支持上传下载文件)>>").strip() if len(cmd) == 0: continue cmd_str = cmd.split() if cmd_str[0] == 'put': cmd_split = cmd_str[1].split() print(cmd_split) filename = os.path.join(settings.CLIENT_HOME,cmd_split[0]) print(filename) if os.path.isfile(filename): filesize = os.stat(filename).st_size msg_dic = { "action": "put", "filename": cmd_split[0], "size": filesize, } ftp_client.send(json.dumps(msg_dic).encode("utf-8")) f = open(filename, "rb") for line in f: ftp_client.send(line) f.close() else: print(filename, "文件不存在") elif cmd_str[0] == 'get': cmd_split = cmd_str[1].split() print(cmd_split) msg_dic = { "action": "get", "filename": cmd_split[0], } ftp_client.send(json.dumps(msg_dic).encode("utf-8")) filesize = ftp_client.recv(4096) print(filesize) if filesize.isdigit() == False: print('文件不存在') else: filesize = int(filesize) filename = os.path.join(settings.CLIENT_HOME, cmd_split[0]) f = open(filename, "wb") received_size = 0 while received_size < filesize: data = ftp_client.recv(4096) f.write(data) received_size += len(data) else: print("下载完成!") f.close() else: print(''' # put 文件名 #上传文件 # get 文件名 #下载文件 ''')
浙公网安备 33010602011771号