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遍历C盘dll文件的方法
May 06 Python
Python查询阿里巴巴关键字排名的方法
Jul 08 Python
django开发之settings.py中变量的全局引用详解
Mar 29 Python
详解django自定义中间件处理
Nov 21 Python
Python计算时间间隔(精确到微妙)的代码实例
Feb 26 Python
python实现大文本文件分割
Jul 22 Python
python实现证件照换底功能
Aug 20 Python
浅析PEP570新语法: 只接受位置参数
Oct 15 Python
python 基于dlib库的人脸检测的实现
Nov 08 Python
Pytorch之view及view_as使用详解
Dec 31 Python
python实现同一局域网下传输图片
Mar 20 Python
pandas实现导出数据的四种方式
Dec 13 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
在数据量大(超过10万)的情况下
2007/01/15 PHP
php简单对象与数组的转换函数代码(php多层数组和对象的转换)
2011/05/18 PHP
php 操作符与控制结构
2012/03/07 PHP
thinkphp数据查询和遍历数组实例
2014/11/28 PHP
smarty模板引擎中自定义函数的方法
2015/01/22 PHP
微信接口生成带参数的二维码
2017/07/31 PHP
js控制滚动条缓慢滚动到顶部实现代码
2013/03/20 Javascript
JS onmousemove鼠标移动坐标接龙DIV效果实例
2013/12/16 Javascript
js实现感应鼠标图片透明度变化的方法
2015/02/20 Javascript
jQuery中的ajax async同步和异步详解
2015/09/29 Javascript
轻松学习jQuery插件EasyUI EasyUI实现拖放商品放置购物车
2015/11/30 Javascript
jQuery EasyUI提交表单验证
2016/07/19 Javascript
nodeJS(express4.x)+vue(vue-cli)构建前后端分离实例(带跨域)
2017/07/05 NodeJs
微信小程序之多列表的显示和隐藏功能【附源码】
2018/08/06 Javascript
AngularJS发送异步Get/Post请求方法
2018/08/13 Javascript
vue中使用codemirror的实例详解
2018/11/01 Javascript
vue实现动态显示与隐藏底部导航的方法分析
2019/02/11 Javascript
JavaScript+HTML5 canvas实现放大镜效果完整示例
2019/05/15 Javascript
python机器学习理论与实战(四)逻辑回归
2018/01/19 Python
Python检测数据类型的方法总结
2019/05/20 Python
Python OpenCV图像指定区域裁剪的实现
2019/10/30 Python
Ubuntu16.04安装python3.6.5步骤详解
2020/01/10 Python
如何使用 Python 读取文件和照片的创建日期
2020/09/05 Python
Python爬虫进阶之爬取某视频并下载的实现
2020/12/08 Python
HTML5 本地存储实现购物车功能
2017/09/07 HTML / CSS
机电专业体育教师求职信
2013/09/21 职场文书
小学生美德少年事迹
2014/02/02 职场文书
追悼会主持词
2014/03/20 职场文书
绿色学校实施方案
2014/03/31 职场文书
我的中国梦演讲稿500字
2014/08/19 职场文书
2014年自愿离婚协议书
2014/10/10 职场文书
教师批评与自我批评总结
2014/10/16 职场文书
艺术节开幕词
2015/01/28 职场文书
高校自主招生教师推荐信
2015/03/23 职场文书
某某店铺的开业庆典主持词范本
2019/11/25 职场文书
Win11 Build 21996.1 Dev版怎么样? win11系统截图欣赏
2021/11/21 数码科技