python高级ftp开发_python 学习分享-实战篇高级的ftp

#client代码

importsocket,os,pickle,hashlib,sys

floder_path= os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '/user_floder'user_path= os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '/conf'server_db_path= os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + '/server_ftp/db/'

classScoket_ftp(object):#客户端类

def __init__(self):

self.client=socket.socket()defclient_user_register(self):#用户注册

username = input('请输入用户名:').strip()

password= input('请输入密码:').strip()if not os.path.exists(user_path + '/%s'%username) :

pwd_md= hashlib.md5() #md5加密用户密码

pwd_md.update(bytes(password,encoding='utf-8'))

pwd_save=pwd_md.hexdigest()

pickle.dump({'username':username,'password':pwd_save},open(user_path + '/%s'%username,'wb'))

os.makedirs(server_db_path+username)print('创建成功!')else:print('账户已经存在!')defclient_user_login(self):#身份验证

username = input('请输入用户名:').strip()

password= input('请输入密码:').strip()if os.path.exists(user_path + '/%s'%username) :

pwd_md= hashlib.md5() #md5加密用户密码

pwd_md.update(bytes(password,encoding='utf-8'))

pwd_save=pwd_md.hexdigest()

user_dic= pickle.load(open(user_path + '/%s'%username,'rb'))if username == user_dic['username'] and pwd_save == user_dic['password'] :print('%s登录成功'%username)returnusernameelse:print('账户密码错误!')returnFalseelse:print('账户密码错误!')returnFalsedefclient_conn(self,ip_addr,port):#建立连接

while 1:

username=self.client_user_login()ifusername :

self.client.connect((ip_addr, port))

self.client.send(username.encode())print(self.client.recv(1024).decode())break

else:continue

defhelp(self):#帮助信息

print('''-----------help-----------

look:查看当前目录下文件

open foldername:打开文件夹

get filename:下载文件

put filename:上传文件''')defclient_interaction(self):#交互

while 1:

self.help()

cmd= input('请输入操作命令:').strip()if len(cmd.split()) == 1: #判断命令行长度,如果是1的话,在判断输入

if cmd == 'look':

self.file_look()#使用look方法

elif cmd == 'exit':

self.file_exit()else:print('命令输入错误,请重新输入')continue

elif len(cmd.split()) == 2: #长度为2,证明是带有前面的语句的

cmd_option, filename =cmd.split()if hasattr(self,'file_' +cmd_option):

func= getattr(self,'file_' +cmd_option)

func(filename)else:continue

else:continue

deffile_look(self):#查看

self.client.send('look'.encode()) #发送方法

print(self.client.recv(1024).decode()) #服务器确认信息,后面可以加入判断,判断服务器目前状态是否正常

self.client.send('please give me!'.encode()) #自动发送给服务器

print('文件目录:',self.client.recv(1024).decode()) #接收目录信息并打印

deffile_get(self,filename):#下载

self.client.send('get'.encode()) #先发送方法

print(self.client.recv(1024).decode()) #服务器确认信息,后面可以加入判断,判断服务器目前状态是否正常

self.client.send(filename.encode()) #再发送文件名称

confirm = self.client.recv(1024).decode() #服务器确认文件是否存在,如果存在返回文件大小,如果不存在,返回no

if confirm != 'no':

self.client.send('please give me!'.encode())

f= open(floder_path+'/'+filename,'wb') #在下载文件夹中创建该文件(如果存在,则替换)

confirm_cal =0

rate= 1

while confirm_cal 1024: #确保接受的准确性,拒绝粘包.

cal = 1024

else:

cal= int(confirm) -confirm_cal

data=self.client.recv(cal)

confirm_cal+= len(data) #避免tcp拆包

f.write(data)if int(confirm) > 102400:if confirm_cal > int(confirm)/100*(rate+1) and rate<= 100:

rate+= 1r= '\r[%s]%d%%' % ("=" *rate, rate)

sys.stdout.write(r)

sys.stdout.flush()else:continue

else:

r= '[%s]%d%%'%('='*100,100)

sys.stdout.write(r)

f.close()

self.client.send('{}下载完成'.format(filename).encode()) #返回服务器信息,表示下载完成

f_1 = open(floder_path+'/'+filename,'rb') #判断一致性

m2 =hashlib.md5()

m2.update(f_1.read())

f_1_m2=m2.hexdigest()

f_1.close()

f_1_m2_server= self.client.recv(1024).decode()if f_1_m2 ==f_1_m2_server :print('\n下载完成!')

self.client.send('客户端已经成功获取完整文件!'.encode())else:print('传输异常')

self.client.send('客户端获取文件不完整或存在异常!'.encode())else:print('确认信息为no,文件可能不存在或有其他问题!')deffile_put(self,filename):#上传文件

self.client.send('put'.encode()) #先发送方法

print(self.client.recv(1024).decode()) #服务器确认信息,后面可以加入判断,判断服务器目前状态是否正常

if os.path.isfile(floder_path + '/' +filename):

self.client.send(filename.encode())print(self.client.recv(1024).decode()) #拒绝粘包

cal = os.stat(floder_path + '/' + filename).st_size #获取文件大小

self.client.send(str(cal).encode()) #发送文件大小信息

print(self.client.recv(1024).decode()) #获取反馈

f = open(floder_path+'/'+filename,'rb') #打开文件

self.client.send(f.read())

f.close()

f_1= open(floder_path + '/' + filename, 'rb') #一致性校验

m2 =hashlib.md5()

m2.update(f_1.read())

f_1_m2=m2.hexdigest()

f_1.close()

f_1_m2_server= self.client.recv(1024).decode()if f_1_m2 ==f_1_m2_server:print('上传完成!')

self.client.send('客户端已经成功上传完整文件!'.encode())else:print('传输异常')

self.client.send('客户端上传文件不完整或存在异常!'.encode())print(self.client.recv(1024).decode())else:

self.client.send('no'.encode())print('查无此文件')deffile_open(self,filename):

self.client.send('open'.encode()) #先发送方法

print(self.client.recv(1024).decode()) #服务器确认信息,后面可以加入判断,判断服务器目前状态是否正常

self.client.send(filename.encode()) #发送目录名称

print(self.client.recv(1024).decode())

self.client.send('防止粘包'.encode())

confirm= self.client.recv(1024).decode() #服务器确认文件是否存在,如果存在返回yes,如果不存在,返回no

if confirm != 'no':

self.client.send('please give me!'.encode()) #自动发送给服务器

file_dir = self.client.recv(1024).decode()print(file_dir)else:print('确认信息为no,目录可能不存在或有其他问题!')if __name__ == '__main__':

socket_ftp=Scoket_ftp()

option= input('''---------option----------

1.创建用户

2.登录

3.退出''').strip()if option == '1':

socket_ftp.client_user_register()elif option == '2':

socket_ftp.client_conn('localhost',6969)

socket_ftp.client_interaction()elif option == '3':

exit()else:print('wrong!')

exit()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值