详解Python3的TFTP文件传输


Posted in Python onJune 26, 2018

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, connfd): 
  self.connfd = connfd 
 
 def do_list(self): 
  # 获取列表 
  file_list = os.listdir(FILE_PATH) 
  # 如果对应的路径内没有文件,返回Empty 
  if not file_list: 
   self.connfd.send('Empty'.encode()) 
   return 
  # 路径存在文件,向客户端发送OK 
  else: 
   self.connfd.send(b'OK') 
   time.sleep(0.1) 
 
  files = "" 
  for file in file_list: 
   # 排除以'.'开头的隐藏文件 
   if file[0] != '.' and \ 
     os.path.isfile(FILE_PATH + file): 
    files = files + file + '#' 
  # 返回文件列表 
  self.connfd.send(files.encode()) 
 
 # 下载文件功能 
 def do_get(self, filename): 
  try: 
   fd = open(FILE_PATH + filename, 'rb') 
  except: 
   self.connfd.send("File doesn't exist".encode()) 
   return 
  # 如果能正常打开,发送OK 
  self.connfd.send(b"OK") 
  time.sleep(0.1) 
  # 开始发送文件 
  try: 
   for line in fd: 
    self.connfd.send(line) 
   fd.close() 
  except Exception as e: 
   print(e) 
  time.sleep(0.1) 
  self.connfd.send(b'##') 
  print("File send over") 
 
 # 开始上传文件 
 def do_put(self, filename): 
  try: 
   fd = open(FILE_PATH + filename, 'w') 
  except: 
   self.connfd.send("Some error") 
  # 如果能正常打开文件,则发送OK 
  self.connfd.send(b'OK') 
  # 开始发送 
  while True: 
   # data为文件内容 
   data = self.connfd.recv(1024).decode() 
   if data == "##": 
    break 
   fd.write(data) 
  fd.close() 
  print("上传完毕")

④主流程控制

def main():
 # 创建套接字/地址/端口
 HOST = '0.0.0.0'
 PORT = 8888
 ADDR = (HOST, PORT)

 sockfd = socket()
 # 设置端口可重用
 sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
 # 绑定地址
 sockfd.bind(ADDR)
 # 设置监听队列大小
 sockfd.listen(5)

 signal.signal(signal.SIGCHLD, signal.SIG_IGN)
 print("Listen to port 8888....")

 while True:
  try:
   connfd, addr = sockfd.accept()
  except KeyboardInterrupt:
   sockfd.close()
   sys.exit("Server exit")
  except Exception as e:
   print(e)
   continue
  print("Client login:", addr)
  # 创建父子进程
  pid = os.fork()
  if pid < 0:
   print("Process creation failed")
   continue
  elif pid == 0:
   # 子进程负责请求接收和发送,所以节省资源,关闭连接套字
   sockfd.close()
   tftp = TftpServer(connfd)
   # 接收客户端请求
   while True:
    data = connfd.recv(1024).decode()
    if not data:
     continue
    # 调用do_list方法获取文件列表
    elif data[0] == 'L':
     tftp.do_list()
    # data ==> G filename
    # 文件名以G开头,以空格为间隔发送过来
    elif data[0] == 'G':
     filename = data.split(' ')[-1]
     tftp.do_get(filename)
    elif data[0] == 'P':
     filename = data.split(' ')[-1]
     tftp.do_put(filename)
    elif data[0] == 'Q':
     print("客户端退出")
     sys.exit(0)

  else:
   connfd.close()
   continue

⑤运行主控制流程,等待客户端连接

if __name__ == "__main__": 
 main()

第二部分,TftpClient

①导入相关模块

from socket import * 
import sys 
import time

②实现基本的请求功能

class TftpServer(object):
 def __init__(self, sockfd):
  self.sockfd = sockfd

 def do_list(self):
  self.sockfd.send(b"L") # 发送请求类型
  # 等待接收服务器端确认
  data = self.sockfd.recv(1024).decode()
  if data == 'OK':
   data = self.sockfd.recv(4096).decode()
   files = data.split('#')
   for file in files:
    print(file)
   print("%%%%%There is file list%%%%%\n")
  else:
   # 失败的原因由服务器发送过来
   print(data)

 def do_get(self, filename):
  self.sockfd.send(('G '+filename).encode())
  data = self.sockfd.recv(1024).decode()
  if data == 'OK':
   fd = open(filename, 'w')
   while True:
    data = self.sockfd.recv(1024).decode()
    if data == "##":
     break
    fd.write(data)
   fd.close()
   print("%s Download over\n" % filename)
  else:
   print(data)

 def do_put(self, filename):
  try:
   fd = open(filename, 'rb')
  except:
   print("There is no such file")
   return
  self.sockfd.send(("P " + filename).encode())
  data = self.sockfd.recv(1024).decode()
  if data == 'OK':
   for line in fd:
    self.sockfd.send(line)
   fd.close()
   time.sleep(0.1)
   self.sockfd.send(b'##')
   print("%s upload over" % filename)
  else:
   print(data)

 def do_quit(self):
  self.sockfd.send(b'Q')

③主流程控制

# 套接字连接
def main():
 if len(sys.argv) < 3:
  print("argv is error")
  return
 HOST = sys.argv[1]
 PORT = int(sys.argv[2])
 ADDR = (HOST, PORT)

 sockfd = socket()
 sockfd.connect(ADDR)

 tftp = TftpServer(sockfd) # tftp对象调用请求方法

 while True:
  print("=======命令选项========")
  print("******* list *********")
  print("*******get file ******")
  print("*******put file ******")
  print("******* quit *********")
  print("======================")

  cmd = input("请输入命令>>")

  if cmd.strip() == 'list':
   tftp.do_list()
  elif cmd[:3] == "get":
   filename = cmd.split(' ')[-1]
   tftp.do_get(filename)
  elif cmd[:3] == "put":
   filename = cmd.split(' ')[-1]
   tftp.do_put(filename)
  elif cmd.strip() == "quit":
   tftp.do_quit()
   sockfd.close()
   sys.exit("Welcome")
  else:
   print("Enter the right order!!!")
   continue

④运行客户端

if __name__ == "__main__": 
 main()

第三部分,展示

详解Python3的TFTP文件传输

一下就不做逐一显示,如有问题,烦请之处修正,共同进步!

Python 相关文章推荐
Python linecache.getline()读取文件中特定一行的脚本
Sep 06 Python
python中的对象拷贝示例 python引用传递
Jan 23 Python
跟老齐学Python之永远强大的函数
Sep 14 Python
详解python中xlrd包的安装与处理Excel表格
Dec 16 Python
python爬虫自动创建文件夹的功能
Aug 01 Python
python url 参数修改方法
Dec 26 Python
详解python列表(list)的使用技巧及高级操作
Aug 15 Python
Python3.x+迅雷x 自动下载高分电影的实现方法
Jan 12 Python
Django media static外部访问Django中的图片设置教程
Apr 07 Python
Eclipse配置python默认头过程图解
Apr 26 Python
python中rc1什么意思
Jun 19 Python
Numpy中np.random.rand()和np.random.randn() 用法和区别详解
Oct 23 Python
python3爬取数据至mysql的方法
Jun 26 #Python
python清除函数占用的内存方法
Jun 25 #Python
Python IDLE清空窗口的实例
Jun 25 #Python
Python设置在shell脚本中自动补全功能的方法
Jun 25 #Python
PyCharm代码整体缩进,反向缩进的方法
Jun 25 #Python
Python代码块批量添加Tab缩进的方法
Jun 25 #Python
对python中for、if、while的区别与比较方法
Jun 25 #Python
You might like
php set_time_limit(0) 设置程序执行时间的函数
2010/05/26 PHP
PHP判断文章里是否有图片的简单方法
2014/07/26 PHP
2014年最新推荐的10款 PHP 开发框架
2014/08/01 PHP
PHP反射机制用法实例
2014/08/28 PHP
Laravel中使用FormRequest进行表单验证方法及问题汇总
2016/06/19 PHP
PHP文件打开关闭及读写操作示例解析
2020/08/06 PHP
JQuery 学习笔记 选择器之五
2009/07/23 Javascript
潜说js对象和数组
2011/05/25 Javascript
jQuery Masonry瀑布流插件使用详解
2014/11/17 Javascript
jquery中EasyUI使用技巧小结
2015/02/10 Javascript
jQuery插件实现适用于移动端的地址选择器
2016/02/18 Javascript
AngularJS基础 ng-cloak 指令简单示例
2016/08/01 Javascript
vue.js入门教程之基础语法小结
2016/09/01 Javascript
基于JS组件实现拖动滑块验证功能(代码分享)
2016/11/18 Javascript
前端开发之CSS原理详解
2017/03/11 Javascript
ES6新数据结构Map功能与用法示例
2017/03/31 Javascript
JS实现点击li标签弹出对应的索引功能【案例】
2019/02/18 Javascript
详解React项目中碰到的IE问题
2019/03/14 Javascript
jQuery Migrate 插件用法实例详解
2019/05/22 jQuery
在vue中利用全局路由钩子给url统一添加公共参数的例子
2019/11/01 Javascript
jstree中的checkbox默认选中和隐藏示例代码
2019/12/29 Javascript
Vue 的双向绑定原理与用法揭秘
2020/05/06 Javascript
vue 手机物理监听键+退出提示代码
2020/09/09 Javascript
Window10+Python3.5安装opencv的教程推荐
2018/04/02 Python
使用python根据端口号关闭进程的方法
2018/11/06 Python
Python结合Window计划任务监测邮件的示例代码
2020/08/05 Python
俄罗斯化妆品和香水网上商店:Iledebeaute
2019/01/03 全球购物
Fossil加拿大官网:化石手表、手袋、首饰及配饰
2019/04/23 全球购物
澳大利亚100%丝绸多彩度假装商店:TheSwankStore
2019/09/04 全球购物
美体小铺法国官方网站:The Body Shop法国
2020/06/04 全球购物
领班岗位职责范文
2014/02/06 职场文书
安全责任协议书
2014/04/21 职场文书
2014年社区党建工作汇报材料
2014/11/02 职场文书
财务管理制度范本
2015/08/04 职场文书
十个Python自动化常用操作,即拿即用
2021/05/10 Python
vue项目支付功能代码详解
2022/02/18 Vue.js