详解Python3的TFTP文件传输

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() 

第三部分,展示

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

(0)

相关推荐

  • Python实现FTP文件传输的实例

    FTP一般流程 FTP对应PASV和PORT两种访问方式,分别为被动和主动,是针对FTP服务器端进行区分的,正常传输过程中21号端口用于指令传输,数据传输端口使用其他端口. PASV:由客户端发起数据传输请求,服务器端返回并携带数据端口,并且服务器端开始监听此端口等待数据,为被动模式: PORT:客户端监听端口并向服务器端发起请求,服务器端主动连接此端口进行数据传输,为主动模式. 其中TYPE分两种模式,I对应二进制模式.A对应ASCII模式: PASV为客户端发送请求,之后227为服务器端返回

  • 详解Python3的TFTP文件传输

    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, c

  • 详解python中的文件与目录操作

    详解python中的文件与目录操作 一 获得当前路径 1.代码1 >>>import os >>>print('Current directory is ',os.getcwd()) Current directory is D:\Python36 2.代码2 如果将上面的脚本写入到文件再运行 Current directory is E:\python\work 二 获得目录的内容 Python代码 >>> os.listdir (os.getcwd

  • 详解Python3.8+PyQt5+pyqt5-tools+Pycharm配置详细教程

    个人使用环境 WIN10x64系统,Python3.8,PyCharm2020.01.03 安装过程 一.安装Python3.8 (自己参考其他教程) 二.安装PyQt5 然后在cmd下输入指令 pip install PyQt5 也可以输入这个指令 pip install PyQt5 -i https://pypi.douban.com/simple (后面是豆瓣的镜像地址,是为了加快下载速度) 提示你更新pip,就按照提示更新(这步骤是可选的,看个人需求) 在cmd下输入 python -m

  • 详解JavaWeb如何实现文件上传和下载功能

    目录 1. 文件传输原理及介绍 2. JavaWeb文件上传 2.1我们用一个新的方式创建项目 2.2 导包 2.3 实用类介绍 2.4 pom.xml导入需要的依赖 2.5 index.jsp 2.6 info.jsp 2.7 FileServlet 2.8 配置Servlet 2.9 测试结果 3. SpringMVC文件上传和下载 3.1 上传 3.2 下载 1. 文件传输原理及介绍 2. JavaWeb文件上传 2.1我们用一个新的方式创建项目 空项目会直接弹出框 把jdk版本设置好 点

  • 详解 Python 读写XML文件的实例

    详解 Python 读写XML文件的实例 Python 生成XML文件 from xml.dom import minidom # 生成XML文件方式 def generateXml(): impl = minidom.getDOMImplementation() # 创建一个xml dom # 三个参数分别对应为 :namespaceURI, qualifiedName, doctype doc = impl.createDocument(None, None, None) # 创建根元素 r

  • 详解Java读取本地文件并显示在JSP文件中

    详解Java读取本地文件并显示在JSP文件中 当我们初学IMG标签时,我们知道通过设置img标签的src属性,能够在页面中显示想要展示的图片.其中src的值,可以是磁盘目录上的绝对,也可以是项目下的相对路径,还可以是网络上的图片路径.在存取少量图片的情况下,采用相对路径存储图片的情况下最方便,也最实用.但是当图片数量过多时,这种方式就显的有些掣肘了. 当系统的图片数量过多时,如果仍把这些图片当做项目的一部分去发布,势必会大大延长项目的发布时间及更新时间.对于某些对于时限性要求特别高的系统来说,采

  • 详解Python3 中hasattr()、getattr()、setattr()、delattr()函数及示例代码数

    hasattr()函数 hasattr()函数用于判断是否包含对应的属性 语法: hasattr(object,name) 参数: object--对象 name--字符串,属性名 返回值: 如果对象有该属性返回True,否则返回False 示例: class People: country='China' def __init__(self,name): self.name=name def people_info(self): print('%s is xxx' %(self.name))

  • 详解Python3 pandas.merge用法

    摘要 数据分析与建模的时候大部分时间在数据准备上,包括对数据的加载.清理.转换以及重塑.pandas提供了一组高级的.灵活的.高效的核心函数,能够轻松的将数据规整化.这节主要对pandas合并数据集的merge函数进行详解.(用过SQL或其他关系型数据库的可能会对这个方法比较熟悉.)码字不易,喜欢请点赞!!! 1.merge函数的参数一览表 2.创建两个DataFrame 3.pd.merge()方法设置连接字段. 默认参数how是inner内连接,并且会按照相同的字段key进行合并,即等价于o

  • 示例详解Python3 or Python2 两者之间的差异

    每门编程语言在发布更新之后,主要版本之间都会发生很大的变化. 在本文中,Vinodh Kumar 通过示例解释了 Python 2 和 Python 3 之间的一些重大差异,以帮助说明语言的变化. 本教程主要介绍内容: 表达式 Print 选项 Unequal 操作 Range 自动迁移 性能问题 主要的内部事务更改 1.表达式 在 Python 2 中为获得计算表达式,你会键入: 但在 Python 3 中,你会键入: 因此,无论我们输入什么,值都会分配给 2 和 3 中的变量 x.当在 Py

  • 对sklearn的使用之数据集的拆分与训练详解(python3.6)

    研修课上讲了两个例子,融合一下. 主要演示大致的过程: 导入->拆分->训练->模型报告 以及几个重要问题: ①标签二值化 ②网格搜索法调参 ③k折交叉验证 ④增加噪声特征(之前涉及) from sklearn import datasets #从cross_validation导入会出现warning,说已弃用 from sklearn.model_selection import train-test_split from sklearn.grid_search import Gri

随机推荐