python实现ftp文件传输功能

本文实例为大家分享了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的文件传输测试,效果如下:

程序升级:

前面的代码还没添加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 环境下运行,结果如下:

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

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

此时可以看到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()

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

(0)

相关推荐

  • Python实现FTP文件传输的实例

    FTP一般流程 FTP对应PASV和PORT两种访问方式,分别为被动和主动,是针对FTP服务器端进行区分的,正常传输过程中21号端口用于指令传输,数据传输端口使用其他端口. PASV:由客户端发起数据传输请求,服务器端返回并携带数据端口,并且服务器端开始监听此端口等待数据,为被动模式: PORT:客户端监听端口并向服务器端发起请求,服务器端主动连接此端口进行数据传输,为主动模式. 其中TYPE分两种模式,I对应二进制模式.A对应ASCII模式: PASV为客户端发送请求,之后227为服务器端返回

  • 详解Python3的TFTP文件传输

    TFTP文件传输 功能: 1.获取文件列表 2.上传文件 3.下载文件 4.退出 第一部分,TftpServer部分. ①导入相关模块 from socket import * import os import signal import sys import time ②确定文件路径 # 文件库路径 FILE_PATH = "/home/tarena/" ③建立一个类,用来实现服务器功能模块 class TftpServer(object): def __init__(self, c

  • python基于FTP实现文件传输相关功能代码实例

    这篇文章主要介绍了python基于FTP实现文件传输相关功能代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 本实例有文件传输相关功能,包括:文件校验.进度条打印.断点续传 客户端示例: import socket import json import os import hashlib CODE = { '1001':'重新上传文件' } def file_md5(file_path): obj = open(file_path,'rb

  • python实现ftp文件传输系统(案例分析)

    最近做了一个简单的文件传输系统,基于ftp协议,使用python语言开发,虽然python里面已经有ftplib模块,可以很容易的实现ftp服务器.这次我使用的是socket实现client与ftp server之间的通讯和文件传输,client另起一个flask服务器,用于用户在浏览器端的交互.系统实现的功能有:用户登录注册,用户查看ftp服务器端文件和下载上传删除操作,支持多进程.多用户. 一,登录注册 该项目使用的是mongo数据库,其实用户登录注册功能很好实现,没有什么技术细节,这里就略

  • python实现FTP文件传输的方法(服务器端和客户端)

    用python实现FTP文件传输,包括服务器端和客户端,要求 (1)客户端访问服务器端要有一个验证功能 (2)可以有多个客户端访问服务器端 (3)可以对重名文件重新上传或下载 FTP(File Transfer Protocol,文件传输协议) 是 TCP/IP 协议组中的协议之一.FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端.其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP协议访问位于FTP服务器上的资源.在开发网站的时候,通常利用FTP协议把网页或程序传

  • python实现ftp文件传输功能

    本文实例为大家分享了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() pri

  • 基于python实现FTP文件上传与下载操作(ftp&sftp协议)

    前言 FTP(File Transfer Protocol)是文件传输协议的简称.用于Internet上的控制文件的双向传输.同时,它也是一个应用程序(Application).用户可以通过它把自己的PC机与世界各地所有运行FTP协议的服务器相连,访问服务器上的大量程序和信息.如果用户需要将文件从自己的计算机上发送到另一台计算机上,可使用FTP上传(upload)或(put)操作,而更多种的情况是用户使用FTP下载(download)或获取(get)操作从FTP服务器上下载文件 在传输文件时我们

  • python多进程实现文件下载传输功能

    本文实例为大家分享了python多进程实现文件下载传输功能的具体代码,供大家参考,具体内容如下 需求: 实现文件夹拷贝功能(包括文件内的文件),并打印拷贝进度 模块: os模块 multiprocessing 模块 代码: import multiprocessing import os def deal_file(old_dir,new_dir,file_name,queue): # 打开以存在文件 old_file = open(os.path.join(old_dir,file_name)

  • C#语言使用gRPC、protobuf(Google Protocol Buffers)实现文件传输功能

    初识gRPC还是一位做JAVA的同事在项目中用到了它,为了C#的客户端程序和java的服务器程序进行通信和数据交换,当时还是对方编译成C#,我直接调用. 后来,自己下来做了C#版本gRPC编写,搜了很多资料,但许多都是从入门开始?调用说"Say Hi!"这种官方标准的入门示例,然后遇到各种问题-- 关于gRPC和Protobuf介绍,就不介绍了,网络上一搜一大把,随便一抓都是标准的官方,所以直接从使用说起. gPRC源代码:https://github.com/grpc/grpc: p

  • Python实现FTP文件定时自动下载的步骤

    之前遇到技术问题总能在技术博客上得到启发,十分感谢各位的无私分享.而自己却很少发文,固然是水平有限,但也限制了知识积累和总结.今后多总结分享,回馈博客的同时也希望大家多多批评. 一.需求: 某数据公司每日15:00~17:00之间,在其FTP发布当日数据供下载,我方需及时下载当日数据至指定本地目录. 二.分析: 1.需实现FTP登陆.查询.下载功能: 解答:使用内置的ftplib模块中FTP类: 2.需判断文件是否下载: 解答:使用os模块中path.exists方法: 3.需判断在指定时间段内

  • java使用Apache工具集实现ftp文件传输代码详解

    本文主要介绍如何使用Apache工具集commons-net提供的ftp工具实现向ftp服务器上传和下载文件. 一.准备 需要引用commons-net-3.5.jar包. 使用maven导入: <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.5</version> </depend

  • python 实现批量文件加密功能

    目录 一.源码 1.结果展示 2.源码 二.源码注释 1.所使用依赖包 2.函数功能 3.代码拓展 三.可运行环境 一.源码 1.结果展示   python自动化办公现在可不是一个陌生的词,也随着人们对自己隐私越来越看重,就会出现这样的需求:每人一个PDF文件,因有个人隐私信息,所以需要对文件进行加密且密码为本人身份证后六位.   废话不多说,上结论,程序运行结果如下:   我们去一探究竟,原文件如下:    获取密码如下:   将文件加密以后结果如下:   我们随机打开一个验证一下:   输入

随机推荐