SELECT版FTP
SELECT版FTP:
使用SELECT或SELECTORS模块实现并发简单版FTP
允许多用户并发上传下载文件
1 import json 2 import select 3 import socket 4 import queue 5 import os,sys 6 7 8 # os.chdir(os.pardir) 9 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 10 print(BASE_DIR) 11 msg_data = "%s/data"%BASE_DIR 12 print(msg_data) 13 14 server = socket.socket() 15 server_addr = ("localhost",1000) 16 server.bind(server_addr) 17 server.listen(7) 18 inputs = [server,] 19 outputs = [] 20 message_queue ={} 21 22 while True: 23 readable,writeable,exeptional = select.select(inputs,outputs,inputs) 24 # 存放所有的活动 25 for sock in readable: 26 if sock is server: 27 conn, client_addr = sock.accept() 28 inputs.append(conn) 29 message_queue[conn] = queue.Queue() #为防阻塞,先把信息存入队列 30 else: 31 data = sock.recv(1024) 32 if data: 33 message_queue[sock].put(data) 34 if sock not in outputs: 35 outputs.append(sock) 36 else: 37 if sock in outputs: 38 outputs.remove(sock) 39 inputs.remove(sock) 40 del message_queue[sock] 41 # 42 # 存放连接信息 43 # 44 for sock in writeable: 45 try: 46 cmd = message_queue[sock].get_nowait() 47 except queue.Empty: 48 outputs.remove(sock) 49 else: 50 print("recv data:", cmd) 51 data = json.loads(cmd.decode()) 52 if data.get('action') is not None: 53 # 54 # 上传文件 55 if data['action'] == 'put': 56 # client sends file to server 57 filename = "%s/%s" % (msg_data,data['filename']) 58 file_obj = open(filename, 'wb') 59 received_size = 0 60 sock.send(b'1') 61 while True: 62 if received_size == data['size']: 63 break 64 recv_data = sock.recv(1024) 65 file_obj.write(recv_data) 66 received_size += len(recv_data) 67 if received_size == data['size']: 68 print('Successfully received file ', data['filename']) 69 file_obj.close() 70 # 71 # 下载文件 72 elif data['action'] == 'get': 73 filename = "%s/%s" % (msg_data, data['filename']) 74 print(filename) 75 76 if os.path.isfile(filename): 77 data['file_size'] = os.path.getsize(filename) 78 data['ERROR'] = '0' 79 else: 80 data['ERROR'] = '777' #ERROR标识 81 sock.send(json.dumps(data).encode()) 82 if os.path.isfile(filename): 83 if sock.recv(1) == b'1': #等待客户端响应,防粘包 84 if data['ERROR'] == '0': 85 file_obj = open(filename, 'rb') 86 for line in file_obj: 87 sock.send(line) 88 # 89 # 其他命令 90 else: 91 data['cmd'] = data['cmd'].upper() 92 sock.send(json.dumps(data).encode()) 93 94 # 95 # 错误链接 96 for sock in exeptional: 97 if sock in outputs: 98 outputs.remove(sock) 99 inputs.remove(sock) 100 del message_queue[sock]
1 import json 2 import socket 3 import os 4 5 # os.chdir(os.pardir) 6 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 7 print(BASE_DIR) 8 msg_data = "%s/data"%BASE_DIR 9 print(msg_data) 10 11 server_address = ('localhost', 1000) 12 sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) 13 sock.connect(server_address) 14 print('''------Welcome!!----- 15 (helps:帮助信息)''') 16 while True: 17 cmd = input(">>>").strip() 18 cmd_list = cmd.split() 19 # 20 #上传文件 21 if cmd_list[0] == 'put': 22 if len(cmd_list) == 1: #命令不能识别 23 print('No filename follows after put cmd!') 24 continue 25 filename = "%s/%s" % (msg_data, cmd_list[1])#将所有的文件都归入data文件夹 26 # print(filename) 27 if os.path.isfile(filename): 28 file_obj = open(filename,'rb') 29 base_filename = filename.split('/')[-1] 30 data_header = { 31 'action':'put', 32 'filename':base_filename, 33 'size':os.path.getsize(filename) 34 } 35 sock.send(json.dumps(data_header).encode()) 36 if sock.recv(1) == b'1': #防止粘包 37 for line in file_obj: 38 sock.send(line) 39 file_obj.close() 40 print('put all file..') 41 else: 42 print('File is not valid') 43 continue 44 # 45 # 下载文件 46 elif cmd_list[0] == 'get': 47 if len(cmd_list) == 1: 48 print('No filename follows after get cmd!') 49 continue 50 file_dir = "%s/%s" %(msg_data,cmd_list[1]) 51 filename= file_dir.split("/")[-1] 52 53 data_header = { 54 'action':'get', 55 'filename':filename, 56 'ERROR':'0' 57 } 58 sock.send(json.dumps(data_header).encode()) 59 data_header = json.loads(sock.recv(1024).decode()) 60 if data_header['ERROR'] == '0': 61 file_obj = open(data_header['filename'], 'wb') 62 received_size = 0 63 sock.send(b'1') 64 while True: 65 66 if received_size == data_header['file_size']: 67 break 68 recv_data = sock.recv(1024) 69 file_obj.write(recv_data) 70 received_size += len(recv_data) 71 72 print('Successfully received file ', data_header['filename']) 73 file_obj.close() 74 # 75 # 帮助信息 76 elif cmd_list[0] == 'helps': 77 print(''' 78 put 文件名 #上传文件 79 get 文件名 #下载文件 80 ''') 81 # 82 # 其他命令 83 else: 84 data_header = { 85 'action':'else', 86 'cmd':cmd 87 } 88 sock.send(json.dumps(data_header).encode()) 89 data_recv = json.loads(sock.recv(1024).decode()) 90 print(data_recv['cmd'])