网络编程
位置:首页>> 网络编程>> Python编程>> Python Socketserver实现FTP文件上传下载代码实例

Python Socketserver实现FTP文件上传下载代码实例

作者:Kong-Ming  发布时间:2022-10-10 11:03:04 

标签:Python,Socket,server,ftp,上传,下载

一、Socketserver实现FTP,文件上传、下载

目录结构

Python Socketserver实现FTP文件上传下载代码实例

1、socketserver实现ftp文件上传下载,可以同时多用户登录、上传、下载

效果图:

Python Socketserver实现FTP文件上传下载代码实例

Python Socketserver实现FTP文件上传下载代码实例

Python Socketserver实现FTP文件上传下载代码实例

二、上面只演示了下载,上传也是一样的,来不及演示了,上代码

1、客户端


import socket,hashlib,os,json,sys,time
class Ftpclient(object):
 def __init__(self):
   self.client = socket.socket()

def connect(self,ip,port):
   self.client.connect((ip, port))
 def help(self):
   msg='''
   ls

pwd

cd ..

get filename

put filename

'''
   print(msg)

def interactive(self):
   """
   客户端入口
   :return:
   """
   while True:
     verify = self.authenticate() #服务器端认证
     if verify:
       while True:
         cmd = input('输入命令 >>').strip()
         if len(cmd) == 0:continue
         cmd_str = cmd.split()[0]
         if hasattr(self,'cmd_%s' %cmd_str):
           func = getattr(self,'cmd_%s' %cmd_str)
           func(cmd)
         else:
           self.help()

def cmd_put(self,*args):
   """
   上传文件
   :param args:
   :return:
   """
   cmd_solit = args[0].split()
   start_time = self.alltime() # 开始时间
   if len(cmd_solit) > 1:
     filename = cmd_solit[1]
     if os.path.isfile(filename):
       filesize = os.stat(filename).st_size
       msg_dic = {
         'filename':filename,
         'size':filesize,
         'overridden':True,
         'action':cmd_solit[0]
       }

self.client.send( json.dumps(msg_dic).encode('utf-8'))
       server_respinse=self.client.recv(1024) #防止粘包,等服务器确认返回
       print('文件开始上传',server_respinse)
       client_size = 0
       f = open(filename,'rb')
       for line in f:
         client_size += self.client.send(line)
         self.processBar(client_size,filesize) #进度条
       else:
         print('文件传输完毕,大小为 %s'%client_size)
         end_time = self.alltime()       # 结束时间
         print('本次上传花费了%s 秒'%self.alltime(end_time,start_time))
         f.close()
     else:
       print(filename,'文件不存在')
   else:
     print('输入有误!')

def cmd_get(self,*args):
   """
   下载文件
   :param args:
   :return:
   """
   cmd_solit = args[0].split()
   start_time = self.alltime() # 开始时间
   filename = cmd_solit[1]
   if len(cmd_solit) > 1:
     msg_dic = {
       'filename': filename,
       'size': '',
       'overridden': True,
       'action': cmd_solit[0],
       'file_exist':''
     }
     self.client.send(json.dumps(msg_dic).encode('utf-8'))
     self.data = self.client.recv(1024).strip()

cmd_dic = json.loads(self.data.decode('utf-8'))
     print(cmd_dic)
     if cmd_dic['file_exist']:
       if os.path.isfile(filename):
         f = open(filename + '.new', 'wb')
       else:
         f = open(filename, 'wb')

self.client.send(b'200 ok')   #防止粘包,等服务器确认返回
       client_size = 0
       filesize = cmd_dic['size']
       m = hashlib.md5()
       while client_size < filesize:
         data=self.client.recv(1024)
         f.write(data)
         client_size +=len(data)
         m.update(data)
         self.processBar(client_size, filesize)
       else:
         print('下载完毕')
         end_time = self.alltime()  # 结束时间
         print('本次下载花费了%s 秒' % self.alltime(end_time, start_time))
         f.close()
         new_file_md5 = m.hexdigest()
         server_file_md5 = self.client.recv(1024)
         print('MD5', server_file_md5,new_file_md5)

else:
       print('下载的 %s文件不存在'%filename)

else:
     print('输入有误!')

def cmd_dir(self,*arge):
   cmd_solit = arge[0].split()
   if len(cmd_solit) > 0:
     msg_dic = {
       'action': cmd_solit[0]
     }
     self.client.send(json.dumps(msg_dic).encode())
     cmd_dir = self.client.recv(1024)
     print(cmd_dir.decode())

else:
     print('输入错误!')

def alltime(self,*args):
   """
   计算上传、下载时间
   :param args:
   :return:
   """
   if args:
     return round(args[0] - args[1])
   else:
     return time.time()

def processBar(self,num, total):
   """
   进度条
   :param num:文件总大小
   :param total: 已存入文件大小
   :return:
   """
   rate = num / total
   rate_num = int(rate * 100)
   if rate_num == 100:
     r = '\r%s>%d%%\n' % ('=' * int(rate_num /3), rate_num,)
   else:
     r = '\r%s>%d%%' % ('=' * int(rate_num /3), rate_num,)
   sys.stdout.write(r)
   sys.stdout.flush

def authenticate(self):
   """
   用户加密认证
   :return:
   """
   username = input('输入用户名:>>')
   password = input('输入密码:>>')
   m = hashlib.md5()
   if len(username) > 0 and len(password) >0:
     username = ''.join(username.split())
     password = ''.join(password.split())
     m.update(username.encode('utf-8'))
     m.update(password.encode('utf-8'))

m = {
       'username':username,
       'password':password,
       'md5':m.hexdigest()
     }
     self.client.send(json.dumps(m).encode('utf-8'))
     server_user_md5 = self.client.recv(1024).strip()
     print(server_user_md5.decode())
     if server_user_md5.decode() == 'success':
       print('登录成功!')
       return 'ok'
     else:
       print('用户名密码错误!')
   else:
     print('请输入用户名密码')

f = Ftpclient()
f.connect('localhost',9999)
f.interactive()

2、服务器端


import socketserver,json,os,hashlib,sys,paramiko
import settings
class Mysocketserver(socketserver.BaseRequestHandler):
 def put(self,*args):
   '''
   接受客户端上传文件
   :return:
   '''
   cmd_dic = args[0]
   filename = cmd_dic['filename'] #获取文件名
   filesize= cmd_dic['size']    #获取文件大小(字节)

if os.path.isfile(filename):  #判断文件是否存在
     f = open(filename + '.new','wb')
   else:
     f = open(filename, 'wb')

self.request.send(b'200 ok')  #防止粘包
   print('%s 文件开始上传' % self.client_address[0])
   received_size = 0
   while received_size < filesize:
     data = self.request.recv(1024)
     f.write(data)
     received_size += len(data)
   else:
     print('文件传输完毕',filename)

def get(self, *args):
   '''
   客户端下载文件
   :return:
   '''
   msg_dic = {
     'filename': '',
     'size': '',
     'overridden': True,
     'action': '',
     'file_exist': ''
   }

cmd_solit = args[0]
   filename = cmd_solit['filename']
   file_exist = os.path.isfile(filename)
   msg_dic['file_exist'] = file_exist
   print(file_exist)
   if file_exist:
     filesize = os.stat(filename).st_size

msg_dic['filename'] = filename
     msg_dic['size'] = filesize
     msg_dic['action'] = cmd_solit['action']

self.request.send(json.dumps(msg_dic).encode('utf-8'))
     server_respang = self.request.recv(1024) #防止粘包
     print('开始传输',server_respang)
     f = open(filename,'rb')
     m = hashlib.md5()
     for lien in f:
       m.update(lien)
       self.request.send(lien)
     else:
       print('传输完成')
       f.close()
       self.request.send(m.hexdigest().encode())
   else:
     print('文件不存在')
     self.request.send(json.dumps(msg_dic).encode('utf-8'))
 def client_authentication(self):
   """
   客户端认证
   :return:
   """
   self.client_user= self.request.recv(1024).strip()
   client_xinxi = json.loads(self.client_user.decode('utf-8'))
   try:
     with open(settings.school_db_file + client_xinxi['username'],'rb') as f:
       data = json.load(f)
       if data['md5'] == client_xinxi['md5']: #判断用户输入是否和服务器端MD5是否一致
         print('验证成功!')
         self.request.send('success'.encode())
         return 'success'
       else:
         self.request.send('error'.encode())
   except Exception as e:
     print('没有此用户',e)
     self.request.send('error'.encode())
 def dir(self,*args):
   """
   查看目录
   :param args:
   :return:
   """
   cmd_split = args[0]
   dd=cmd_split['action']
   result_os = os.popen(dd).read()
   self.request.send(result_os.encode())

def handle(self):
   """
   服务器端入口
   :return:
   """
   while True:
     try:
       success = self.client_authentication()
       if success:
         self.data=self.request.recv(1024).strip()
         cmd_dic = json.loads(self.data.decode('utf-8'))
         action = cmd_dic['action']
         if hasattr(self,action):
           func = getattr(self,action)
           func(cmd_dic)
     except ConnectionResetError as e:
       print('连接断开',self.client_address[0])
       break
if __name__ == '__main__':

HOST,PORT='localhost',9999
 server=socketserver.ThreadingTCPServer((HOST,PORT),Mysocketserver)
 server.serve_forever()

settings.py 文件


import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DB_FILE = os.path.join(BASE_DIR, "data\\")
school_db_file = os.path.join(DB_FILE)
print(school_db_file)

data里两个做测试的文件,

alex 文件内容:
 {"username": "alex", "password": "123456", "md5": "94e4ccf5e2749b0bfe0428603738c0f9"}

kml123456文件内容:
{"username": "kml123456", "password": "123456","md5": "a791650e70ce08896e3dafbaa7598c26"}

到这里差不多就没了,

来源:https://www.cnblogs.com/km-thonder/p/12579302.htm

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com