import socket

import hashlib

importstructimport os

import settingclass FtpClient(object):

features= ['get', 'put', 'ls', 'cd', 'mkdir', 'rm'] # 客户端提供的命令提供功能

def __init__(self, server_ip, port, user, pwd):''':param server_ip: 服务器ip

:param port: 服务器端口

:param user: 用户名

:param pwd: 密码''' self.server_ip =server_ip

self.port=port

self.user=user

self.pwd=pwd

self.sock=socket.socket() # 初始化时创建套接字try:

self.sock.connect((self.server_ip, self.port)) # 连接服务器

except ConnectionRefusedError:

print('501', setting.CODE['501'])returnself.pwd_hash() # 密码hashifnot self.auth():return# 验证失败

# self.run() # 登录成功继续操作

def pwd_hash(self): # 对用户输入密码进行hash

md5= hashlib.md5(setting.MD5_SALT.encode('utf-8'))

md5.update(self.pwd.encode('utf-8'))

self.pwd=md5.hexdigest()

def auth(self): # 上传用户密码进行验证

account= ','.join([self.user, self.pwd])

self.sock.send(account.encode('utf-8'))

auth_result= self.sock.recv(1024).decode() # 获取登录结果if auth_result == '8000':

print(auth_result, setting.CODE[auth_result])

self.run()else:

print(auth_result, setting.CODE[auth_result])

self.sock.close()returnFalse

def run(self):whileTrue:

user_input= input('\n>>>').strip() # 用户输入命令

command=user_input.split()

self.cmd= command[0] # 获取命令前缀if self.cmd == 'exit': # 检测到exit则退出

self.sock.close()break

else:if self.cmd inself.features: # 判断命令是否支持

self.command_s= user_input.encode('utf-8')

func=getattr(self, self.cmd) # 使用反射获取命令对应方法if len(command) == 1:if command[0] in ['get', 'put', 'cd', 'mkdir', 'rm']:

print(setting.CODE['4000'])continuefunc()

elif len(command)== 2:

func(command[1])else:

print(setting.CODE['4000'])else:

print(setting.CODE['4000'])

defget(self, *args, **kwargs):

self.send_cmd(self.command_s)

filename= args[0]

file_stat= self.sock.recv(4).decode('utf-8') # 接收文件是否找到状态码if file_stat == '1000':

tmp_file= filename + '.tmp'file_path=os.path.join(setting.DOWNLOAD_DIR, tmp_file) # 存放文件路径

real_path=os.path.join(setting.DOWNLOAD_DIR, filename)

tmp_size= 0

ifnot os.path.exists(file_path):

self.sock.sendall(b'2000')else:

self.sock.sendall(b'2001')

tmp_size=os.path.getsize(file_path)

self.sock.sendall(self.struck_info(tmp_size))

file_size= struct.unpack('i', self.sock.recv(4))[0] # 接收文件大小

receive_size= 0receive_size+=tmp_size

with open(file_path,'ab') asf:while receive_size

data= self.sock.recv(file_size -receive_size)else:

data= self.sock.recv(1024)ifnot data:

print('文件下载中断!')returnreceive_size+=len(data)

f.write(data)

self.toolbar(receive_size, file_size)

print()

src_md5= self.sock.recv(1024).decode('utf-8')

dec_md5=self.file_md5(file_path)if src_md5 ==dec_md5:

print('{}下载成功!'.format(filename))

os.rename(file_path, real_path)else:

print('文件一致性校验失败,上传失败')

os.remove(file_path)else:

print(setting.CODE[file_stat])

def put(self,*args, **kwargs):'''上传文件,断点续传

:param args:

:param kwargs:

:return:''' ifargs: # args为文件名

file_name= args[0]ifos.path.exists(file_name): # 判断文件是否存在

self.send_cmd(self.command_s)

file_size=os.path.getsize(file_name)

self.sock.send(self.struck_info(file_size)) # 发送文件大小

ques= self.sock.recv(1024).decode('utf-8') # 获取是否需要断点续传

send_size= 0# 发送的数据计数

with open(file_name,'rb') asf: # 打开文件if ques == 'all_file': # 发送整个文件

start_index= 0

else:

start_index= int(ques) # 获取断点文件大小

f.seek(start_index)

send_size+=start_indexfor line inf:

self.sock.sendall(line) # 发送数据

send_size+=len(line)

self.toolbar(send_size, file_size) # 进度条

print()

src_md5=self.file_md5(file_name) # 文件md5

self.sock.send(src_md5.encode('utf-8')) # 发送自己文件的md5

result= self.sock.recv(1024).decode('utf-8') # 获取md5比对结果,

print(result)else:

print('{} file not found!'.format(file_name))

def ls(self,*args, **kwargs):

self.send_cmd(self.cmd.encode('utf-8'))'''接收打印服务器发送的当前目录信息

:param args:

:param kwargs:

:return:''' info = self.sock.recv(4)

info_size= struct.unpack('i', info)[0] # 接收数据长度

receive_size= 0info= b''

while receive_size

data_size= 1024

if info_size - receive_size < 1024:

data_size= info_size -receive_size

data=self.sock.recv(data_size)

info+=data

receive_size+=len(data)

print(info.decode('utf-8')) # 打印目录结构

def cd(self,*args, **kwargs):'''切换目录

:param args:

:param kwargs:

:return:'''self.send_cmd(self.command_s)

print(setting.CODE[self.sock.recv(4).decode()]) # 打印切换结果

def mkdir(self,*args, **kwargs):'''创建目录

:param args:

:param kwargs:

:return:'''self.send_cmd(self.command_s)

status= self.sock.recv(1024).decode('utf-8')

print(setting.CODE[status])

def rm(self,*args, **kwargs):'''删除文件或者目录

:param args:

:param kwargs:

:return:'''self.send_cmd(self.command_s)

status= self.sock.recv(1024).decode('utf-8')

print(setting.CODE[status])

def struck_info(self, info_size):'''打包数据

:param info_size:

:return:''' return struct.pack('i', info_size)

def send_cmd(self, cmd):'''发送命令长度包和命令信息包

:param cmd:

:return:'''self.sock.send(self.struck_info(len(cmd)))

self.sock.send(cmd)

def file_md5(self, file):'''获取文件md5

:param file:

:return:''' md5 =hashlib.md5()

with open(file,'rb') asf:for i inf:

md5.update(i)returnmd5.hexdigest()

def toolbar(self, current, total):'''打印进度条

:param current:

:param total:

:return:''' val = current / total * 100print('\r{}{:.2f}%'.format(int(val) //2 * '>', val), end='')

if __name__ == '__main__':

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

pwd= input('请输入密码').strip()

cli= FtpClient('127.0.0.1', 8001, user, pwd)

python ftp服务器限速_python实现ftp服务器相关推荐

  1. python tcp服务器并发_python tcp并发服务器

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  2. python怎么重启内核_python怎么重启服务器

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  3. python远程文件管理系统_python 读取远程服务器文件

    几个提高工作效率的Python内置小工具 在这篇文章里,我们将会介绍4个Python解释器自身提供的小工具.这些小工具在笔者的日常工作中经常用到,减少了各种时间的浪费,然而,却很容易被大家忽略.每当有 ...

  4. python 文件下载服务器异常_python 从远程服务器下载日志文件的程序

    import os import sys import ftplib import socket ################################################### ...

  5. python 简单web音频_Python Twisted web服务器音频fi

    我尝试用python中的twisted创建一个简单的web服务器.不过,我无法提供m4a音频文件.在 在当前程序中,当我加载http://localhost:8880/mp3.html时,它可以正常工 ...

  6. python分析服务器日志_python实现web服务器日志分析脚本

    python日志分析脚本 用python可以实现大日志文件的分析,比如查到sql注入语句,然后看到IP,就可以改下脚本,用IP为特征取出日志,分析入侵过程. python比较shell脚本的优点是速度 ...

  7. python下载文件传到服务器_python实现FTP文件传输的方法(服务器端和客户端)

    用python实现FTP文件传输,包括服务器端和客户端,要求 (1)客户端访问服务器端要有一个验证功能 (2)可以有多个客户端访问服务器端 (3)可以对重名文件重新上传或下载 FTP(File Tra ...

  8. python sftp连接_python 进行ftp服务器和sftp服务器连接

    1.背景. 最近接到一个任务,需要写一个python脚本,从客户公司的服务器拉取图片存放到我们公司的sftp服务器. 由于没头没脑,所以我采用无限遍历,将对方服务器中文件的路径原原本本的复制到我们公司 ...

  9. python下载文件传到服务器_python实现FTP文件传输(服务器端和客户端)

    用python实现FTP文件传输,包括服务器端和客户端,要求 (1)客户端访问服务器端要有一个验证功能 (2)可以有多个客户端访问服务器端 (3)可以对重名文件重新上传或下载 FTP(File Tra ...

最新文章

  1. 稍等片刻 正在提取文件_三亚种子罐市场价,中药提取浓缩设备的价格
  2. [转] ubuntu 无线网络 配置 virtualbox
  3. 同盟与对抗:谈《少女杜拉的故事》中的治疗关系(转)
  4. HALCON示例程序inspect_solar_fingers.hdev太阳能电池板电路缺陷检测
  5. WiFi行业将走向何方?
  6. 这 6 个开源工具 yyds
  7. ktv 上传图片 1218
  8. ios10 申请拍照权限_iOS10配置申请权限
  9. 本周四直播:Oracle 19c 升级实战分享
  10. Powerdesigner设置表字段注释与name相同
  11. Openjudge-计算概论(A)-字符串排序
  12. 将图片放大如何保持图片的清晰度?
  13. 快速上手Onvif(Python)心得
  14. python爬取微博内容_python如何抓取新浪微博的微博内容!
  15. 网站服务器的宽带是1mb是什么意思,1mb/s网速是什么意思
  16. 分类问题:如何解决样本分布不均衡
  17. 直方图均衡化高斯滤波
  18. ubuntu 调 2K 分辨率
  19. 【译】将字符转换为双精度浮点型
  20. 数学之美读书笔记第一章

热门文章

  1. (草稿)如何判断一名UiPath开发人员是否合格?
  2. 看完这篇你们团队的代码也很规范
  3. css overflow: scroll 去滚动条后,低端手机有兼容问题,可以这样
  4. 【C语言】输入一个字符串,并对字符串中的偶数位置的字符按从小到大的顺序排序,奇数位置的字符不动,输出排序后的结果...
  5. PicGo复制自定义链接
  6. javascript 代码_如何使您JavaScript代码简单易读
  7. html css js速成_CSS速成课程
  8. 交付方式 saas_扩展和交付SaaS启动的最佳方法
  9. d3 canvas_D3和Canvas分3个步骤
  10. SAS在金融中的应用七