详解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程序代码的几种方法总结
Apr 28 Python
简单谈谈Python流程控制语句
Dec 04 Python
详解Python list 与 NumPy.ndarry 切片之间的对比
Jul 24 Python
Python将多个list合并为1个list的方法
Jun 27 Python
python利用requests库进行接口测试的方法详解
Jul 06 Python
使用 Python 实现简单的 switch/case 语句的方法
Sep 17 Python
Python 实现中值滤波、均值滤波的方法
Jan 09 Python
Django2 连接MySQL及model测试实例分析
Dec 10 Python
使用Python三角函数公式计算三角形的夹角案例
Apr 15 Python
Python调用C/C++的方法解析
Aug 05 Python
Python脚本打包成可执行文件过程解析
Oct 20 Python
一个入门级python爬虫教程详解
Jan 27 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
ThinkPHP中ajax使用实例教程
2014/08/22 PHP
PHP下载生成的csv文件及问题总结
2015/08/06 PHP
Yii基于数组和对象的Model查询技巧实例详解
2015/12/28 PHP
利用Homestead快速运行一个Laravel项目的方法详解
2017/11/14 PHP
Yii2框架实现登陆添加验证码功能示例
2018/07/12 PHP
javascript 兼容FF的onmouseenter和onmouseleave的代码
2008/07/19 Javascript
让 JavaScript 轻松支持函数重载 (Part 2 - 实现)
2009/08/04 Javascript
ASP.NET jQuery 实例4(复制TextBox的文本到本地剪贴板上)
2012/01/13 Javascript
缓动函数requestAnimationFrame 更好的实现浏览器经动画
2012/12/07 Javascript
JavaScript判断变量是否为undefined的两种写法区别
2013/12/04 Javascript
jquery引用方法时传递参数原理分析
2014/10/13 Javascript
Js制作点击输入框时默认文字消失的效果
2015/09/05 Javascript
JavaScript 模块的循环加载实现方法
2015/12/13 Javascript
jQuery1.9+中删除了live以后的替代方法
2016/06/17 Javascript
使用DeviceOne实现微信小程序功能
2016/12/29 Javascript
将鼠标焦点定位到文本框最后(代码分享)
2017/01/11 Javascript
js实现短信发送倒计时功能(正则验证)
2017/02/10 Javascript
babel基本使用详解
2017/02/17 Javascript
Webpack实现按需打包Lodash的几种方法详解
2017/05/08 Javascript
layui 设置table 行的高度方法
2018/08/17 Javascript
angular4自定义组件非input元素实现ngModel双向数据绑定的方法
2018/12/28 Javascript
js实现随机div颜色位置 类似满天星效果
2019/10/24 Javascript
JS运算符简单用法示例
2020/01/19 Javascript
Openlayers实现扩散的动态点(水纹效果)
2020/08/17 Javascript
通过JS判断网页是否为手机打开
2020/10/28 Javascript
python数组过滤实现方法
2015/07/27 Python
使用Python生成随机密码的示例分享
2016/02/18 Python
Python程序打包工具py2exe和PyInstaller详解
2019/06/28 Python
探索HTML5本地存储功能运用技巧
2016/03/02 HTML / CSS
浅谈html5标签css3的常用样式
2016/10/20 HTML / CSS
公司财务工作总结的自我评价
2013/11/23 职场文书
计算机毕业大学生推荐信
2013/12/01 职场文书
新员工入职感言
2014/02/01 职场文书
犯错检讨书
2014/02/21 职场文书
电子专业毕业生自荐信
2014/05/25 职场文书
为什么在foreach循环中JAVA集合不能添加或删除元素
2021/06/11 Java/Android