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

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

项目地址

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

实操预览

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

思维导图

文件传输系统

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

原理

基于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

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

往期精彩

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

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

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

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

  1. python聊天小程序支持私聊和多人_利用Python打造一个多人在线匿名聊天的小程序!(前后端完整开发)...

    用Python打造一个多人在线匿名聊天的小程序(附代码) 最近看到好多设计类网站, 都提供了多人在线匿名聊天的小功能, 感觉很有意思, 于是自己就用django框架写了一个, 支持手动实时更名, py ...

  2. python读压缩文件内容_使用Python读写及压缩和解压缩文件的示例

    读写文件 首先看一个例子: f = open('thefile.txt','w') #以写方式打开, try: f.write('wokao') finally: f.close() 文件的打开方式: ...

  3. python制作音乐模块_用Python打造一个只属于你的专属音乐播放器,享受动手的快乐!...

    平常我们总是用爬虫爬取网页上的音乐,今天我们换个玩法,用Python制作一个独一无二只属于你的音乐播放器,小伙伴们觉得如何?如果觉得提议还不错,那就立即动手吧! 一.需要的库 pygame tkint ...

  4. python将csv文件拆分_在python中将一个csv拆分为多个文件

    我在python中有一个约5000行的csv文件,我想将其拆分为五个文件. 我为此写了一个代码,但是没有用 import codecs import csv NO_OF_LINES_PER_FILE ...

  5. 如何用python新建文件夹_用Python编写一个每天都在系统下新建一个文件夹的脚本...

    这个程序的功能非常的简单,就是每天在系统中新建一个文件夹.文件夹即当前的时间.此代码是在同事那边看到的,为了锻炼下自己薄弱的Python能力,所以花时间重新写了一个.具体代码如下: import ti ...

  6. python读取多个文件夹_在python中如何从不同的文件夹读取多个文件

    我在不同的文件夹中有年度数据文件.每个文件包含从1月1日到12月31日的每日数据.数据文件名类似于AS060419.67,其中最后四位代表年份,即1967年,0604是文件夹名.在 我试图使用下面的代 ...

  7. python随机抽取人名_用Python打造一个CRM系统(五)

    在上一篇上实现了线索功能模块,在实际使用中除了线索数据除了输入的结构化数据,也有可能是来自非结构化数据,如名片.PDF文档.语音视频等.为方便线索录入,本篇中将以名片为例,实现利用OCR等技术将名片信 ...

  8. python开发出来的crm系统_用Python打造一个CRM系统(三)

    在上一篇中我们基于cookiecutter-django创建了一个one_crm的项目,在本文中将在本地进行初始化,并成功运行起来. 本地初始化之前先确保环境先安装了Python3.8.Postgre ...

  9. python写一个crm系统_用Python打造一个CRM系统(四)

    在上一篇中在本地进行初始化,并让项目顺利运行.在本篇中将实现一个线索管理模块,支持线索的增删改查. 新建线索应用模块 进入项目目录,使用django命令创建线索应用模块,命令如下: $ python ...

最新文章

  1. 今天做内存操作系统(xp装在内存中)
  2. linux如何取文件列名,Linux_根据表名和索引获取需要的列名的存储过程,复制代码 代码如下: create proc p - phpStudy...
  3. C/C++由字符串转JSON/JSON转字符串/数组解析/数组添加
  4. Sublime Text for Mac的快捷键
  5. 169. 多数元素 golang
  6. Visual Basic 终于要衰落了吗?
  7. python一个对象只能被一个变量引用吗_Python中的变量、对象、引用
  8. html中src为空,怎么解决img里面src为空状态下的边框问题
  9. oracle参数文件与启动过程
  10. 【Java】Java速成
  11. Apache的管理优化
  12. PV操作经典例题——和尚打水
  13. Python写的Web spider(网络爬虫)
  14. Node.js的环境搭建方法和 npm 的使用方法
  15. Unnecessary escape character: \- no-useless-escape eslint
  16. python图片切割以及识别图片中的文字
  17. 你又不杀狼人,何必非要银弹?
  18. 第五章 指向数组的指针
  19. 浏览器只有百度不能上网,其他网站上网正常
  20. 手机壳 套图 软件 imageEn(Delphi实现)

热门文章

  1. locker server启动
  2. 百度 android geocoding,百度地图经纬度批量查找功能XGeocoding使用手册(示例代码)
  3. potplayer 皮肤_如何美化背部皮肤?
  4. mysql空事务死锁_mysql空当锁导致死锁_mysql
  5. Monthly Expense POJ - 3273(二分最大值最小化)
  6. 八种基本排序方式(插入排序,希尔排序,选择排序,冒泡排序,快速排序,堆排序,归并排序,基数排序)代码模板以及时间复杂度
  7. WSDM 2022 | 一种用于在线广告自动竞价的协作竞争多智能体框架
  8. tornado服务器动态文件,tornado 实现服务器消息推送功能
  9. java矩阵加法_在java中的数组加法?
  10. 如何设置运行在Virtualbox内的Ubuntu虚拟机的静态ip地址