详解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 14 Python
Python安装使用命令行交互模块pexpect的基础教程
May 12 Python
Matplotlib 生成不同大小的subplots实例
May 25 Python
Tensorflow使用tfrecord输入数据格式
Jun 19 Python
python中map的基本用法示例
Sep 10 Python
Python用5行代码写一个自定义简单二维码
Oct 21 Python
python实现控制台打印的方法
Jan 12 Python
pyhanlp安装介绍和简单应用
Feb 22 Python
用python做游戏的细节详解
Jun 25 Python
Python3实现汉语转换为汉语拼音
Jul 08 Python
解决pytorch GPU 计算过程中出现内存耗尽的问题
Aug 19 Python
Python Matplotlib绘制等高线图与渐变色扇形图
Apr 14 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同时支持GIF、png、JPEG
2006/10/09 PHP
PHP的变量总结 新手推荐
2011/04/18 PHP
PHP生成唯一的促销/优惠/折扣码(附源码)
2012/12/28 PHP
php Imagick获取图片RGB颜色值
2014/07/28 PHP
PHP中使用imagick实现把PDF转成图片
2015/01/26 PHP
PHP遍历XML文档所有节点的方法
2015/03/12 PHP
Nginx服务器上安装并配置PHPMyAdmin的教程
2015/08/18 PHP
php框架CodeIgniter主从数据库配置方法分析
2018/05/25 PHP
实例介绍PHP删除数组中的重复元素
2019/03/03 PHP
javascript JSON操作入门实例
2010/04/16 Javascript
JavaScript和CSS通过expression实现Table居中显示
2013/06/28 Javascript
getAsDataURL在Firefox7.0下无法预览本地图片的解决方法
2013/11/15 Javascript
node.js中的fs.readSync方法使用说明
2014/12/17 Javascript
javascript简单实现滑动菜单效果的方法
2015/07/27 Javascript
JavaScript实现瀑布流布局
2020/06/28 Javascript
jQuery插件autocomplete使用详解
2017/02/04 Javascript
jQuery中each方法的使用详解
2018/03/18 jQuery
用ES6的class模仿Vue写一个双向绑定的示例代码
2018/04/20 Javascript
前端插件之Bootstrap Dual Listbox使用教程
2019/07/23 Javascript
JS实现点击发送验证码 xx秒后重新发送功能
2019/07/30 Javascript
JavaScript实现身份证验证代码实例
2019/08/26 Javascript
Vue循环中多个input绑定指定v-model实例
2020/08/31 Javascript
[04:27]2014DOTA2国际邀请赛 NAVI战队官方纪录片
2014/07/21 DOTA
Python同时向控制台和文件输出日志logging的方法
2015/05/26 Python
Python机器学习之SVM支持向量机
2017/12/27 Python
Python代码块批量添加Tab缩进的方法
2018/06/25 Python
Python3 使用selenium插件爬取苏宁商家联系电话
2019/12/23 Python
Python如何在DataFrame增加数值
2020/02/14 Python
HTML table 表格边框的实现思路
2019/10/12 HTML / CSS
数学兴趣小组活动总结
2014/07/08 职场文书
党组织领导班子整改方案
2014/10/25 职场文书
2014年统计工作总结
2014/11/21 职场文书
火锅店的开业营销方案范本!
2019/07/05 职场文书
2019通用版导游词范本!
2019/08/07 职场文书
Python卷积神经网络图片分类框架详解分析
2021/11/07 Python
使用Redis实现点赞取消点赞的详细代码
2022/03/20 Redis