详解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 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
Mar 19 Python
python实现决策树、随机森林的简单原理
Mar 26 Python
详解python异步编程之asyncio(百万并发)
Jul 07 Python
对python生成业务报表的实例详解
Feb 03 Python
手把手教你使用Python创建微信机器人
Apr 29 Python
python实现视频分帧效果
May 31 Python
简单了解python的一些位运算技巧
Jul 13 Python
Python写出新冠状病毒确诊人数地图的方法
Feb 12 Python
浅谈Pycharm最有必要改的几个默认设置项
Feb 14 Python
opencv 形态学变换(开运算,闭运算,梯度运算)
Jul 07 Python
Python 多进程、多线程效率对比
Nov 19 Python
python实现文件+参数发送request的实例代码
Jan 05 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
php5 mysql分页实例代码
2008/04/10 PHP
php文件上传表单摘自drupal的代码
2011/02/15 PHP
微博短链接算法php版本实现代码
2012/09/15 PHP
浅析虚拟主机服务器php fsockopen函数被禁用的解决办法
2013/08/07 PHP
PHP实现数字补零功能的2个函数介绍
2014/05/12 PHP
php版阿里云OSS图片上传类详解
2016/12/01 PHP
jquery入门——事件机制之事件中的冒泡现象示例解释
2020/09/12 Javascript
JavaScript学习笔记之JS函数
2015/01/22 Javascript
JS库之Highlight.js的用法详解
2017/09/13 Javascript
微信小程序实现提交input信息到后台的方法示例
2019/01/19 Javascript
VScode格式化ESlint方法(最全最好用方法)
2019/09/10 Javascript
Layer+Echarts构建弹出层折线图的方法
2019/09/25 Javascript
jQuery实现图片随机切换、抽奖功能(实例代码)
2019/10/23 jQuery
Vue页面切换和a链接的本质区别详解
2019/11/12 Javascript
Vue.extend 编程式插入组件的实现
2019/11/18 Javascript
JavaScript实现电灯开关小案例
2020/03/30 Javascript
小程序实现录音功能
2020/09/22 Javascript
[49:54]Ti4 循环赛第三日 LGD vs Titan
2014/07/12 DOTA
[04:32]玩具屠夫中文语音节选
2020/08/23 DOTA
python测试mysql写入性能完整实例
2018/01/18 Python
Python如何发布程序的详细教程
2018/10/09 Python
在Python 中同一个类两个函数间变量的调用方法
2019/01/31 Python
python3格式化字符串 f-string的高级用法(推荐)
2020/03/04 Python
Python常用base64 md5 aes des crc32加密解密方法汇总
2020/11/06 Python
python安装sklearn模块的方法详解
2020/11/28 Python
美国最大的网络男装服装品牌:Bonobos
2017/05/25 全球购物
美国最大婚纱连锁店运营商:David’s Bridal
2019/03/12 全球购物
北京SQL新华信咨询
2016/09/30 面试题
家长评语大全
2014/01/22 职场文书
高中学生干部学习的自我评价
2014/02/21 职场文书
岗位明星事迹材料
2014/05/18 职场文书
奉献演讲稿范文
2014/05/21 职场文书
司法助理专业自荐书
2014/06/13 职场文书
2014年环卫工作总结
2014/11/22 职场文书
员工工作表现自我评价
2015/03/06 职场文书
MySQL创建管理KEY分区
2022/04/13 MySQL