python实现ftp文件传输功能


Posted in Python onMarch 20, 2020

本文实例为大家分享了python实现ftp文件传输的具体代码,供大家参考,具体内容如下

主要步骤可以分为以下几步:

1.读取文件名
2.检测文件是否存在
3.打开文件
4.检测文件大小
5.发送文件大小和 md5值给客户端
6.等客户端确认
7.开始边读边发数据

服务器端代码:

import socket,os,time
import hashlib
 
server =socket.socket()
server.bind(('0.0.0.0',6666))
server.listen()
print("等待....")
while True:
 conn,addr = server.accept()
 print("new conn:",conn)
 while True:
 data = conn.recv(1024)
 if not data:
 print("client is disconnection")
 break
 cmd,filename = data.decode().split() #记录指令和文件名
 print(filename)
 #判断当前目录是否存在该文件,而且必须是文件,而不是目录
 if os.path.isfile(filename):
 f = open(filename,'rb')
 #m = hashlib.md5() # 创建md5
 file_size = os.stat(filename).st_size #stat() 可以返回文件的大小值
 conn.send((str(file_size)).encode()) # 发送文件大小
 conn.recv(1024) #等待返回信息
 for line in f:
 # m.updata(line) 
 conn.send(line)
 #print("file md5",m.hexdigest()) #打印md5值
 f.close()

客户端代码:

# Author: zjt
import socket
 
client = socket.socket()
 
client.connect(("0.0.0.0",6666))
 
 
while True:
 cmd = input(">>>:").strip()
 
 if len(cmd)==0 :continue
 
 if cmd.startswith("get"):
 client.send(cmd.encode())
 server_response = client.recv(1024)
 print("server response: ",server_response)
 client.send(b"ready to recv file")
 
 # 开始接收文件
 file_total_size = int(server_response.decode())
 received_size = 0 # 记录接收文件的大小
 filename = cmd.split()[1]
 # 因为两个目录一致,接收的文件名不能与原文件相同
 f = open(filename+".new","wb")
 while received_size < file_total_size:
 data = client.recv(1024)
 received_size += len(data)
 f.write(data)
 print("total:",file_total_size," present: ",received_size)
 else:
 print("file has received done!")
 f.close()
 
client.close()

用80M的文件传输测试,效果如下:

python实现ftp文件传输功能

程序升级:

前面的代码还没添加md5进行验证,现在对代码进行升级

服务器端代码:

import socket,os,time
import hashlib
 
server =socket.socket()
server.bind(('0.0.0.0',8888))
server.listen()
print("等待....")
while True:
 conn,addr = server.accept()
 print("new conn:",conn)
 while True:
 data = conn.recv(1024)
 if not data:
 print("client is disconnection")
 break
 cmd,filename = data.decode().split() #记录指令和文件名
 print(filename)
 #判断当前目录是否存在该文件,而且必须是文件,而不是目录
 if os.path.isfile(filename):
 f = open(filename,'rb')
 m = hashlib.md5() # 创建md5
 file_size = os.stat(filename).st_size #stat() 可以返回文件的大小值
 conn.send((str(file_size)).encode()) # 发送文件大小
 conn.recv(1024) #等待返回信息
 for line in f:
 m.update(line)
 conn.send(line)
 print("file md5",m.hexdigest()) #打印md5值
 
 f.close()
 conn.send(m.hexdigest().encode()) # 发送md5
 
 print("我真的已经发过去了",m.hexdigest().encode())
 
 print("send done")
 
server.close()

客户端代码:

import socket
import hashlib
client = socket.socket()
client.connect(("0.0.0.0",8888))
while True:
 cmd = input(">>>:").strip()
 if len(cmd)==0 :continue
 if cmd.startswith("get"):
 client.send(cmd.encode())
 server_response = client.recv(1024)
 print("server response: ",server_response)
 client.send(b"ready to recv file")
 # 开始接收文件
 file_total_size = int(server_response.decode())
 received_size = 0 # 记录接收文件的大小
 filename = cmd.split()[1]
 # 因为两个目录一致,接收的文件名不能与原文件相同
 f = open(filename+".new","wb")
 m = hashlib.md5()
 while received_size < file_total_size:
 data = client.recv(1024)
 received_size += len(data)
 m.update(data)
 f.write(data)
 #print("total:",file_total_size," present: ",received_size)
 else:
 new_file_md5 = m.hexdigest()
 print("client file md5:",new_file_md5)
 print("file has received done!")
 print("total:",file_total_size," present: ",received_size)
 f.close()
 sever_file_md5 = client.recv(1024)
 print("client file md5:",new_file_md5)
 print("server file md5:",sever_file_md5)
client.close()

两个程序在linux 环境下运行,结果如下:

python实现ftp文件传输功能

可以看到传输后文件大小变大了一点点,而且md5前后值也不同,说明文件传输发生了改变。

现在讲程序在windows环境下运行,结果如下:

python实现ftp文件传输功能

此时可以看到windows上没有问题,文件大小相同,且md5值也一致。

原因分析:

之所以会发生这种情况,是因为在linux上运行时,最后一次传输文件与发送md5值的时候,发生可粘包,导致最后一次接收文件的时候,连同md5的数据一并发送了。而客户端也当作一条接收信息,全部接收了。所以客户端出现没有收到来自服务器端的md5值,多出来的那一点点,就是md5值的大小。

解决方法:

在接收文件的时候,判断当前剩余多少文件需要接收,如果大于1024,就接收1024大小的文件,否则就只接收剩下全部的文件,防止最后一次接收多余的数据。

只需要对客户端代码进行修改,修改后代码如下:

import socket
import hashlib
client = socket.socket()
client.connect(("0.0.0.0",8888))
while True:
 cmd = input(">>>:").strip()
 if len(cmd)==0 :continue
 if cmd.startswith("get"):
 client.send(cmd.encode())
 server_response = client.recv(1024)
 print("server response: ",server_response)
 client.send(b"ready to recv file")
 # 开始接收文件
 file_total_size = int(server_response.decode())
 received_size = 0 # 记录接收文件的大小
 filename = cmd.split()[1]
 f = open(filename+".new","wb")
 m = hashlib.md5()
 while received_size < file_total_size:
 #添加一次判断,使最后一次剩多少就接收多少,避免发生粘包
 if file_total_size - received_size > 1024:
  size = 1024
 else: # 最后一次,剩多少收多少
  size = file_total_size - received_size
 data = client.recv(size)
 received_size += len(data)
 m.update(data)
 f.write(data)
 else:
 new_file_md5 = m.hexdigest() 
 print("client file md5:",new_file_md5)
 print("file has received done!")
 print("total:",file_total_size," present: ",received_size)
 print("下一句关闭文件")
 f.close()
 print("开始接收md5 ") 
 sever_file_md5 = client.recv(1024)
 print("client file md5:",new_file_md5)
 print("server file md5:",sever_file_md5)
client.close()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现分析apache和nginx日志文件并输出访客ip列表的方法
Apr 04 Python
在Python中实现贪婪排名算法的教程
Apr 17 Python
基于wxpython开发的简单gui计算器实例
May 30 Python
Python闭包的两个注意事项(推荐)
Mar 20 Python
使用python在本地电脑上快速处理数据
Jun 22 Python
Python实现1-9数组形成的结果为100的所有运算式的示例
Nov 03 Python
Python最火、R极具潜力 2017机器学习调查报告
Dec 11 Python
解决python3捕获cx_oracle抛出的异常错误问题
Oct 18 Python
pywinauto自动化操作记事本
Aug 26 Python
pytorch实现mnist数据集的图像可视化及保存
Jan 14 Python
pytorch dataloader 取batch_size时候出现bug的解决方式
Feb 20 Python
Python 如何解决稀疏矩阵运算
May 26 Python
Python开发之身份证验证库id_validator验证身份证号合法性及根据身份证号返回住址年龄等信息
Mar 20 #Python
python实现FTP文件传输的方法(服务器端和客户端)
Mar 20 #Python
python实现ftp文件传输系统(案例分析)
Mar 20 #Python
关于Python 中的时间处理包datetime和arrow的方法详解
Mar 19 #Python
JetBrains PyCharm(Community版本)的下载、安装和初步使用图文教程详解
Mar 19 #Python
Python文件操作基础流程解析
Mar 19 #Python
Python函数基本使用原理详解
Mar 19 #Python
You might like
php explode函数实例代码
2012/02/27 PHP
PHP中使用json数据格式定义字面量对象的方法
2014/08/20 PHP
php创建图像具体步骤
2017/03/13 PHP
JavaScript加密解密7种方法总结分析
2007/10/07 Javascript
Span元素的width属性无效果原因及解决方案
2010/01/15 Javascript
jQuery对html元素取值与赋值的方法
2013/11/20 Javascript
JS实现图片无间断滚动代码汇总
2014/07/30 Javascript
javascript根据时间生成m位随机数最大13位
2014/10/30 Javascript
node.js中使用socket.io的方法
2014/12/15 Javascript
jQuery判断指定id的对象是否存在的方法
2015/05/22 Javascript
Jquery基础之事件操作详解
2016/06/14 Javascript
jQuery实现动态显示select下拉列表数据的方法
2018/02/05 jQuery
Vue数据双向绑定原理及简单实现方法
2018/05/18 Javascript
react native 原生模块桥接的简单说明小结
2019/02/26 Javascript
详解vuex数据传输的两种方式及this.$store undefined的解决办法
2019/08/26 Javascript
vue实现数字动态翻牌的效果(开箱即用)
2019/12/08 Javascript
[01:31:03]DOTA2完美盛典全回顾 见证十五项大奖花落谁家
2017/11/28 DOTA
Python自动化测试ConfigParser模块读写配置文件
2016/08/15 Python
python 队列详解及实例代码
2016/10/18 Python
Python中函数及默认参数的定义与调用操作实例分析
2017/07/25 Python
Python实现爬虫爬取NBA数据功能示例
2018/05/28 Python
Python爬虫之网页图片抓取的方法
2018/07/16 Python
python版大富翁源代码分享
2018/11/19 Python
django模板加载静态文件的方法步骤
2019/03/01 Python
15个应该掌握的Jupyter Notebook使用技巧(小结)
2020/09/23 Python
韩国三大免税店之一:THE GRAND 中文免税店
2016/07/21 全球购物
HEMA英国:荷兰原创设计
2018/08/28 全球购物
求职简历中的自我评价分享
2013/12/08 职场文书
优秀信贷员先进事迹
2014/01/31 职场文书
市场营销大学生职业规划书
2014/02/25 职场文书
学校就业推荐信范文
2014/05/19 职场文书
美德少年事迹材料1000字
2014/08/21 职场文书
雨雪天气温馨提示
2015/07/15 职场文书
年会邀请函的格式及范文五篇
2019/11/02 职场文书
工厂无线对讲系统解决方案
2022/02/18 无线电
html中相对位置与绝对位置的具体使用
2022/05/15 HTML / CSS