详解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 相关文章推荐
将Emacs打造成强大的Python代码编辑工具
Nov 20 Python
初学python的操作难点总结(新手必看篇)
Aug 03 Python
python中的随机函数random的用法示例
Jan 27 Python
python 实现在Excel末尾增加新行
May 02 Python
对PyQt5中的菜单栏和工具栏实例详解
Jun 20 Python
Python多叉树的构造及取出节点数据(treelib)的方法
Aug 09 Python
Python3监控疫情的完整代码
Feb 20 Python
python3 xpath和requests应用详解
Mar 06 Python
python实现npy格式文件转换为txt文件操作
Jul 01 Python
Django限制API访问频率常用方法解析
Oct 12 Python
python如何调用php文件中的函数详解
Dec 29 Python
Pygame Draw绘图函数的具体使用
Nov 17 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_xmlhttp 乱码问题解决方法
2009/08/07 PHP
php中preg_match的isU代表什么意思
2015/10/01 PHP
thinkPHP中create方法与令牌验证实例浅析
2015/12/08 PHP
php数组实现根据某个键值将相同键值合并生成新二维数组的方法
2017/04/26 PHP
基于Laravel实现的用户动态模块开发
2017/09/21 PHP
jQuery选择没有colspan属性的td的代码
2010/07/06 Javascript
使用js显示当前时间示例
2014/03/02 Javascript
jQuery的缓存机制浅析
2014/06/07 Javascript
extjs 分页使用jsp传递数据示例
2014/07/29 Javascript
使用JavaScript实现ajax的实例代码
2016/05/11 Javascript
浅谈JavaScript的push(),pop(),concat()方法
2016/06/03 Javascript
jQuery中 bind的用法简单介绍
2017/02/13 Javascript
angularjs2 ng2 密码隐藏显示的实例代码
2017/08/01 Javascript
jQuery基于随机数解决中午吃什么去哪吃问题示例
2018/12/29 jQuery
JavaScript递归函数定义与用法实例分析
2019/01/24 Javascript
JavaScript数据结构与算法之基本排序算法定义与效率比较【冒泡、选择、插入排序】
2019/02/21 Javascript
微信小程序导航栏跟随滑动效果的实现代码
2019/05/14 Javascript
微信小程序实现横向滚动导航栏效果
2019/12/12 Javascript
JavaScript字符和ASCII实现互相转换
2020/06/03 Javascript
[01:37]全新的一集《真视界》——TI7总决赛
2017/09/21 DOTA
python实现媒体播放器功能
2018/02/11 Python
Apache,wsgi,django 程序部署配置方法详解
2019/07/01 Python
Django中reverse反转并且传递参数的方法
2019/08/06 Python
浅析PyTorch中nn.Module的使用
2019/08/18 Python
python基于selenium爬取斗鱼弹幕
2021/02/20 Python
css3 矩阵的使用详解
2018/03/20 HTML / CSS
Timberland俄罗斯官方网上商店:全球领先的户外品牌
2020/03/15 全球购物
附答案的Java面试题
2012/11/19 面试题
学生的自我鉴定范文
2013/10/24 职场文书
党员批评与自我批评
2014/02/12 职场文书
2014年办公室主任工作总结
2014/11/12 职场文书
技术员个人工作总结
2015/03/03 职场文书
记者节感言
2015/08/03 职场文书
Python实现天气查询软件
2021/06/07 Python
解析Java中的static关键字
2021/06/14 Java/Android
Python中Numpy和Matplotlib的基本使用指南
2021/11/02 Python