python socket 实现模拟ftp 上传、下载文件

it2022-05-05  163

ftp 实现功能如下:

1、实现多用户登陆,需使用用户名密码校验登陆过程

2、每个用户有自己的加目录

3、可使用ls、cd指令切换查看目录

4、可是实现上传下载文件的功能

5、可以断点续传

 

 

目前只是简单实现,还存在较多bug

客户端代码

#!/usr/bin/python # -*- coding: utf-8 -*- #Author:xianyanghua # @Time :2019/7/9 10:47 # @File : socket_client.py # @Software: PyCharm import struct from socket import * import os import sys class mysocketClient(object): def __init__(self,HOST,PORT,dire=None): self.sock= socket(AF_INET,SOCK_STREAM) self.sock.connect((HOST,PORT)) self.dire=dire def start(self): self.auth() def auth(self): while True: msg=raw_input('请输入用户名密码 username:password >>>') if msg.count(':')==1: self.sock.send(msg.encode('utf-8')) data=self.sock.recv(1024) if data.startswith('你好'): username,password=msg.split(':') self.dire=username self.interactive() else: continue else: print('输入格式有误') continue def interactive(self): while True: print('instruction fuction [filename]') try: if not self.dire: msg = raw_input('>>>>%s '%self.dire) else: msg= raw_input('>>>[%s]'%self.dire ) if msg.count(' ')==1: fuc,filename=msg.split(' ') print('.........1.........') print(fuc,filename) elif not msg: print('不能为空') continue else: fuc=msg filename=None print('2......................') print(fuc,filename) if hasattr(self,fuc): print('...............') func=getattr(self,fuc) print(func) func(filename) except Exception as e: print(e) continue def push(self,filename): print(filename) msg='push '+filename self.sock.send(msg.encode('utf-8')) data = self.sock.recv(1024) print(data) if data.decode('utf-8') == 'ready': file_size = os.path.getsize(filename) print(file_size) length = struct.pack('i', file_size) self.sock.send(length) f = file(filename, 'rb') send_size = 0 while not file_size == send_size: if file_size - send_size > 1024: msg = f.read(1024) send_size += len(msg) else: # left data less than 1024 msg = f.read(file_size - send_size) send_size += (file_size - send_size) self.sock.send(msg) per = int((float(send_size) / float(file_size)) * 100) self.processBar(per) f.close() data = self.sock.recv(1024) if data.decode('utf-8') == 'success': print('') self.sock.send('success'.encode('utf-8')) print('传输完成') def get(self,filename): pass def ls(self,filename): if not filename: self.sock.send('ls'.encode('utf-8')) data=self.sock.recv(1024) print('[[[[]]]') print(data) def cd(self,filename): if not filename: print('filename 不能为空') self.sock.send('cd '+filename) data=self.sock.recv(1024) print(data) if data=='cdSuccess': self.dire=filename print(data) else: print(data) def processBar(self,percent): bar_length = 100 hashes = '#' * int(percent / 100.0 * bar_length) spaces = ' ' * (bar_length - len(hashes)) sys.stdout.write("\rPercent: [%s] %d%%" % (hashes + spaces, percent)) sys.stdout.flush() if __name__=='__main__': HOST='127.0.0.1' PORT=8003 s1=mysocketClient(HOST,PORT) s1.start()

服务端代码

#!/usr/bin/python # -*- coding: utf-8 -*- #Author:xianyanghua # @Time :2019/7/16 12:52 # @File : ftpserver.py # @Software: PyCharm import socketserver import os import sys import struct class MyTCPHandler(socketserver.BaseRequestHandler): def handle(self): try: BASEDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) os.chdir(BASEDIR) os.chdir('ftpserver') userconf={'hua': '123', 'liu': '321'} data=self.request.recv(1024) user,password=data.split(':') if userconf[user]==password: self.request.send('你好'+user+'欢迎登录ftp服务器') platform=sys.platform if platform=='win32': pwd=os.getcwd() os.chdir('hua') pwd = os.getcwd() print(platform,pwd) else: self.request.send('用户名密码错误') self.request.close() except Exception as e: print(e) self.request.close() try: while True: data = self.request.recv(1024) if not data: continue if data=='ls': data=os.listdir('.') print( data) data=str(data) try: if data.startswith('cd'): fuc,filename=data.split(' ') print(data) print (fuc,filename) os.chdir(filename) data='cdSuccess' except Exception as e: print(e) data=e if data.startswith('push'): filename=data.split(' ')[1] self.request.send('ready') print('......') file_size = self.request.recv(4) file_size=struct.unpack('i',file_size)[0] print(file_size,',,,,,,,,,,,') recv_size=0 recv_msg='' f = file(filename, 'wb') while not file_size == recv_size: # 只要文件总大小和已收到的大小不想等,就代表还没收完 if file_size - recv_size > 1024: # 文件总大下减已收到的大小等于还剩下没收到的大小,如果这个数大于1024,代表一次肯定收不完,那就还得多循环几次 data = self.request.recv(1024) # 这次收1024字节,但实际上收到的可能比1024小,所以需要以实际收到的数为准 recv_size += len(data) # 已收到的大小加上这一次循环收到的实际大小 else: # 如果最后剩下的少于1024,那就一次性把剩下的都收过来 data = self.request.recv(file_size - recv_size) # recv_size = file_size #不能这么写,因为这一次依然不一定能一次性收完,因为实际收到的数据可能比你规定的数据要少, 所以需要按下面这行的方式写 recv_size += (file_size - recv_size) f.write(data) print(recv_msg) f.close() self.request.send('success') data=self.request.recv(1024) print(data) continue self.request.send(data) except Exception as e: print(e) self.request.close() print(data) if __name__=='__main__': HOST='127.0.0.1' PORT=8003 server=socketserver.ThreadingTCPServer((HOST,PORT),MyTCPHandler) server.serve_forever()

 


最新回复(0)