linux 查找文件夹_用python打造一个基于socket的文件(夹)传输系统

1a35019ca87b46577d7cc6a3f82ba557.png

这段时间在学习python,接触到了网络编程中的socket这块,加上自己在用的Linux服务器都是原生支持python的,于是乎有了个做文件传输功能程序的想法。

毕竟python语言中,有下载功能的框架一抓一大把,但是主机与主机间快速搭建文件(夹)传输通道的程序似乎不常见,因为我刚接触python不久,但是我不知道也不奇怪,总得来说,自己做一个练手,成就感满满。

项目地址

https://github.com/Ccapton/python-stuff/tree/master/filetransporter

实操预览

75b63855b38847bff354581a922c2b68.png

本地主机发送文件到远端服务器主机。

思维导图

44b604605160c6312a699049f9e502b9.png文件传输系统

以上思维导图仅供参考,毕竟表达能力有限,具体功能要追究到代码处才能分析其原理。

原理

基于socket的通信,相信会编程的朋友都不陌生,而通过socket来传输文件也是很常见的,但是这仅仅是对于单个文件来说很容易实现。

如果是多文件呢?

我在实现本系统之前尝试了几次,用单一socket通道来传输多文件不切实际,因为调用socket.recv()方法的时候,返回的数据格式是原始数据str类型,要分割不同文件的数据有很大难度。

因为涉及到接收、发送方两端文件数据接收和发送进度的统一性,就要用另外的指令来控制传输工作不乱套,于是我想到多开一个socket作为传输指令的通道,这样指令和数据就分离了,也就容易控制传输工作了!所以有了指令线程数据线程之分。

要实现传输整个文件夹,首先要遍历这个文件夹,把在其内的所有文件结构准确无误的还原出来;因为是通过一个socket通过传输数据,所以传输文件只能一个接一个来,这样,文件的遍历工作只能等前一个文件传输完毕后才能继续进行,于是又要对遍历工作设计一番。

经过改造,我在文件查找(遍历)器内加入了while循环体和供外界继承的回调类,这样就能达到我想要的文件通过socket按顺序传输的效果了。

文件查找器FileFinder(阻塞型)源码:

import os,time# 文件、文件夹寻找类 (阻塞型)# 阻塞的设计:为了等待调用者的耗时操作【否则很快就完成了文件的遍历任务,调用者达不到顺序操作文件(夹)的意图】class FileFinder:   def __init__(self,finderCallback):       self.finderCallback = finderCallback       # 文件(夹)路径下所有文件的总大小       self.sum_size = 0       # 调用者控制的参数,若为False,则遍历工作继续进行,若为True,则阻塞任务,等待调用者完成它的其他耗时操作后在考虑是否改变此值       self.recycle = True       # 调用者控制的参数,若为False,则正常工作,若为True,则当recycle为False时遍历工作不阻塞快速完成,recycle为True时遍历工作阻塞       self.off = False    # 文件(夹)找到时的回调类   class FinderCallback:       # 找到文件夹       def onFindDir(self,dir_path):           pass       # 找到文件       def onFindFile(self,file_path,size):           pass       # 预留的刷新函数       def onRefresh(self):           pass   # 查找文件(夹)方法   def list_flie(self,root_dir):       if  os.path.isfile(root_dir):           while self.recycle:               time.sleep(0.05)           if self.finderCallback:               self.finderCallback.onFindFile(root_dir,os.path.getsize(root_dir))               self.finderCallback.onRefresh()               if not self.off:                  self.recycle = True       else:           dirlist = os.listdir(root_dir)  # 列出文件夹下所有的目录与文件           for dir in dirlist:               path = os.path.join(root_dir, dir)               if os.path.isfile(path):                   while self.recycle:                       time.sleep(0.05)                   if self.finderCallback:                       self.finderCallback.onFindFile(path,os.path.getsize(path))                       self.finderCallback.onRefresh()                       if not self.off:                          self.recycle = True               else:                   while self.recycle:                       time.sleep(0.05)                   if self.finderCallback:                       self.finderCallback.onFindDir(path)                       self.finderCallback.onRefresh()                       if not self.off:                          self.recycle = True                   # 递归调用(当遍历到文件夹时,继续遍历,直到当前文件夹下没有文件夹为止)                   self.list_flie(path)
通过继承FileFinder的回调类FinderCallback,重写其 onFindDir(self,dir_path) 和onFindFile(self,file_path,size)方法,在这两个方法里面发送相关指令到接收端。但最难的就是两端的指令线程内的socket指令信息的处理,这需要深入代码去具体研究,本人能力有限,也就不细说了。需要研究一番的朋友,请移步该项目地址 https://github.com/Ccapton/python-stuff/tree/master/filetransporter

注意

运行接收端程序,需要一个能访问的地址,也即是说最好是局域网内进行文件传输工作,因为局域网本地ip都是可以直接访问的,若是在公共网络传输文件,必须知道接收方主机的公网ip和内网ip。例如我现在用到接收方主机是腾讯云的主机,内网ip是10.135.xxx.xxx,公网ip是111.120.xxx.xxx。该主机内,运行接收(服务)端程序
python3 ftserver.py -i 10.135.xxx.xxx -d /home/ubuntu/downloads
而在你的主机运行发送(客户)端程序发送文件夹bilibili
python3 ftclient.py -i 111.120.xxx.xxx -f /Users/capton/desktop/bilibili
因为腾讯云、阿里云等国内虚拟主机供应商是采用NAT地址转换对云主机进行地址分配的,所以按照我上面的步骤来运行两端程序才能连通。

- END -

原文链接:

https://www.jianshu.com/p/07ff2a7d22f4

文源网络,仅供学习之用,如有侵权,联系删除。

往期精彩

f77c01e1175918889028b675de40b3e7.png

◆  50款开源工具你都用过吗?

◆  python+C、C++混合编程的应用

◆  python网络爬虫的基本原理详解

ae4b760d2d78b900df7f0136d12ec134.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/244457.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql gtid 备份恢复_MySQL基于gtid特性与xtrabackup的数据恢复

一、gtid特性介绍:GTID(global transaction identifier)是MySQL 5.6的新特性,可以唯一的标识一个事务,由UUIDTID组成:UUID是MySQL实例的唯一标识TID是该实例上已提交的事务的数量在主从复制中,GTID代替了classic的复制…

编码gbk的不可映射字符_Python基础:编码表和字符的故事

在计算机内部,都是每8位组成的一个个字节,比如我们使用"abc".encode()把abc转化成二进制byte类型,注意byte是不可变类型: 编码过程>>> abc.encode() # 把str字符变为bytes字节类型;字符是一个个连接…

java mysql数据库编程_java JDBC数据库(mysql)编程

什么是JDBC• JDBC(Java Data Base Connectivity,Java数据库连接)• 是一种用于执行SQL语句的Java API,为多种关系数据库提供统一访问• 它由一组用Java语言编写的类和接口组成JDBC访问数据库步骤• 1:加载一个Driver驱动要通过JDBC与数据库连接&#xf…

python数据分析包pandas_Python 数据分析包:pandas 基础

pandas 是基于 Numpy 构建的含有更高级数据结构和工具的数据分析包 类似于 Numpy 的核心是 ndarray,pandas 也是围绕着 Series 和 DataFrame 两个核心数据结构展开的 。Series 和 DataFrame 分别对应于一维的序列和二维的表结构。pandas 约定俗成的导入方法如下&…

mysql 查询分析器中使用if_查询分析器中开发代码测试检查_MySQL

如果您像我一样,则可能已经花费了很多时间在查询分析器中开发代码。在您对代码感到满意之后,可以立即对开发服务器上的测试数据库运行一个或两个专设 测试。如果看起来没有什么问题,您便可以将代码投入生产。如果这是一段关键代码&#xff0c…

python文本清洗_【python】TXT文本数据清洗和英文分词、词性标注

删除空白行def clean_line (raw_file_name save_file_name):张开(raw_file_name, r )作为f_r,开放(save_file_name, w ) f_w: f_r_list 列表(设置(f()))在f_r_list句子:如果句子 \u201C\\ n\u201D: f_r_(句子)f (f_r_list)阅读文本的每一行作为一个列表,然后使用一组集合来删除…

centeros6.8 mysql_centeros7安装mysql8,以及设置root密码

2.点击下载后,在下载页面选择操作系统3.点击下载rpm文件,拿到这个下载链接4.移除mariadb数据库yum remove mariadb-libs.x86_645.进入到/tmp目录使用wget下载wget https://repo.mysql.com//mysql80-community-release-el7-2.noarch.rpm6.安装mysql的源yu…

mysql 中文字段名_MySQL全文索引怎么做?| 教程分享

- 点击上方“爱数据学习社”关注我们吧! -文末领取【商业分析资料】为什么要用全文索引我们在用一个东西前,得知道为什么要用它,使用全文索引无非有以下原因:like查询太慢、json字段查询太慢(车太慢了)没时间引入ElasticSearch、S…

centos php mysql 5.6 安装_centos 6.8 yum安装 PHP 5.6

1.检查当前安装的PHP包。yum list installed | grep php2.如果有安装的PHP包,先删除他们。先复制到文本中,编辑成一行,在执行。yum remove php.x86_64 php-cli.x86_64 php-common.x86_64 php-gd.x86_64 php-ldap.x86_64php-mbstring.x86_64 p…

leftjoin多个on条件_MYSQL|为什么LEFT JOIN会这么慢?

之前谈了怎样后台导出SAP序时账,因为导出的序时账数据量较大(3家主体公司,2017-2020年的数据),用了数据库MYSQL中的LEFT JOIN 来处理连接多表汇总数据,查询太慢啦,后来沦落到用手工分年来汇总数据,然后再导…

python 画布包括不了全部组件?_试验程序:画布版九键琴

近期有读者询问如何制作出滑动琴键连续发出声音的程序,他尝试用一排按钮充当琴键,但每次滑动只能触发一个按钮的点击事件,因此也只能发出一个声音。我提示他用画布替代按钮,他希望给予更具体的提示,于是我索性自己做了…

c 子类对象 访问父类对象受保护成员_06-JavaSe面向对象

一.static1.它是一种修饰符2.使用位置:它用来修饰成员变量和成员方法static修饰成员变量,叫类变量;static修饰成员方法,叫类方法;类成员类变量类方法没有使用static修饰成员变量,叫实例变量;没有…

keil中断函数的写法_在 KeilC里,中断子程序与函数有何不同?( )_学小易找答案

【单选题】8051单片机共有( )个中断优先级【单选题】对定时器 0 进行关中断操作,需要复位中断允许控制寄存器的: ( )【多选题】真理向谬误转化的原因,主要在于( )【多选题】“批判的武器当然不能代替武器的批判,物质的力量只能用物质的力量来摧毁,理论一经群众掌握,也会变成物质…

c++ stack 遍历_C/C++内存分配!

一、预备知识—程序的内存分配一个由c/C编译的程序占用的内存分为以下几个部分1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。2、堆区(heap)…

python读取oracle数据到hvie parquet_关于sparksql操作hive,读取本地csv文件并以parquet的形式装入hive中...

说明:spark版本:2.2.0hive版本:1.2.1需求: 有本地csv格式的一个文件,格式为${当天日期}visit.txt,例如20180707visit.txt,现在需要将其通过spark-sql程序实现将该文件读取并以parquet的格式通过外部表的形式…

el-date-picker设置默认日期_程序员必备:Java 日期处理的十个坑

前言整理了Java日期处理的十个坑,希望对大家有帮助。一、用Calendar设置时间的坑反例:Calendar c Calendar.getInstance();c.set(Calendar.HOUR, 10);System.out.println(c.getTime());运行结果:Thu Mar 26 22:28:05 GMT08:00 2020解析&…

scope python_Python标准库Scope

作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明。谢谢!1 模块简介你一定在很多计算机科学课程上听说过作用域。它很重要,如果你不理解它的工作原理,那么就会出现一些令人…

java命令_JAVA与模式之命令模式

在阎宏博士的《JAVA与模式》一书中开头是这样描述命令(Command)模式的:命令模式属于对象的行为模式。命令模式又称为行动(Action)模式或交易(Transaction)模式。命令模式把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化&#xf…

android 16进制 全透明_你有几种实现方案Android 设备唯一标识?

前言项目开发中,多少会遇到这种需求:获得设备唯一标识DeviceId,用于:1.标识一个唯一的设备,做数据精准下发或者数据统计分析;2.账号与设备绑定;3.....分析这类文章,网上有许多资料&a…

链表的数据域怎么使用结构体_一步一步教你从零开始写C语言链表

为什么要学习链表?链表主要有以下几大特性:1、解决数组无法存储多种数据类型的问题。2、解决数组中,元素个数无法改变的限制(C99的变长数组,C也有变长数组可以实现)。3、数组移动元素的过程中,要对元素进行大范围的移动…