TFTP协议介绍-python实现tftp客户端
1. TFTP协议介绍
TFTP(Trivial File Transfer Protocol,简单文件传输协议)
是TCP/IP协议族中的一个用来在客户端与服务器之间进行简单文件传输的协议
特点:
- 简单
- 占用资源小
- 适合传递小文件
- 适合在局域网进行传递
- 端口号为69
- 基于UDP实现
2. TFTP下载过程
TFTP服务器默认监听69号端口
当客户端发送“下载”请求(即读请求)时,需要向服务器的69端口发送
服务器若批准此请求,则使用一个新的、临时的 端口进行数据传输

当服务器找到需要现在的文件后,会立刻打开文件,把文件中的数据通过TFTP协议发送给客户端
如果文件的总大小较大(比如3M),那么服务器分多次发送,每次会从文件中读取512个字节的数据发送过来
因为发送的次数有可能会很多,所以为了让客户端对接收到的数据进行排序,所以在服务器发送那512个字节数据的时候,会多发2个字节的数据,用来存放序号,并且放在512个字节数据的前面,序号是从1开始的
因为需要从服务器上下载文件时,文件可能不存在,那么此时服务器就会发送一个错误的信息过来,为了区分服务发送的是文件内容还是错误的提示信息,所以又用了2个字节 来表示这个数据包的功能(称为操作码),并且在序号的前面
| 操作码 | 功能 |
|---|---|
| 1 | 读请求,即下载 |
| 2 | 写请求,即上传 |
| 3 | 表示数据包,即DATA |
| 4 | 确认码,即ACK |
| 5 | 错误 |
因为udp的数据包不安全,即发送方发送是否成功不能确定,所以TFTP协议中规定,为了让服务器知道客户端已经接收到了刚刚发送的那个数据包,所以当客户端接收到一个数据包的时候需要向服务器进行发送确认信息,即发送收到了,这样的包成为ACK(应答包)
为了标记数据已经发送完毕,所以规定,当客户端接收到的数据小于516(2字节操作码+2个字节的序号+512字节数据)时,就意味着服务器发送完毕了
TFTP数据包的格式如下:
2. 下载文件用客户端参考代码如下:
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# @Time: 2020/7/2 17:51
# @Author:zhangmingda
# @File: tftp_client.py
# @Software: PyCharm
# Description: 通过socket 使用UDP协议模仿tftp客户端下载文件 from socket import * # 网络套接字工具
import struct #组数包的工具
import sys if len(sys.argv) != 3:
print("USAGE:python %s <Tftp Server IP> <Filename>" % sys.argv[0])
exit(1)
else:
server_ip = sys.argv[1]
filename = sys.argv[2] # 创建UDP套接字
udpSocket = socket(AF_INET, SOCK_DGRAM) # 构造下载请求数据
# '!H%ssb5sb'字段说明:
# ! 表示为网络数据,超过1字节数据,大端方式存储/发送
# H 表示两个字节操作码,对应后面的1
# s 表示文件名的字节长度,表示后面的filename,一个s表示一个字节%s为字符长度数字;
# b 为一个字节长度,对应表示 后面的0
print(filename)
# getCmdPack = struct.pack('!H8sb5sb',1,'test.png',0,"octet",0)
getCmdPack = struct.pack("!H%ssb5sb" % len(filename),1,filename.encode('utf-8'),0,b"octet",0)
# 这里构建发包的字符串必须为字节码方式bytes
# print("发包数据:",getCmdPack) # 指定服务器地址
serverAddr = (server_ip,69) # 发送下载文件请求数据到服务器端
udpSocket.sendto(getCmdPack,serverAddr) # 初始化一个变量,记录返回的包的个数
recv_pack_num = 0 # 死循环接收服务器返回的数据
while True:
#recvfrom 返回两个值,数据和服务端信息
recvData,recvAddr = udpSocket.recvfrom(1024)
recvDataLen = len(recvData)
# print(recvDataLen)
# print(recvAddr) # 解包获取返回的前四个字节,从中获取操作码, H代表每两个字节组成一个数据,H代表2个字节的占位符
# 解包返回的是一个元组
recvCmdTuple = struct.unpack("!H",recvData[:2])
# print("返回的操作码元组为:",recvCmdTuple) # 获取操作码
recvCmd = recvCmdTuple[0] if recvCmd == 3:
# 获取块儿编号元组
recvPackNumTuple = struct.unpack("!H",recvData[2:4])
recvPackNum = recvPackNumTuple[0]
print('块儿编号:',recvPackNum)
if recvPackNum == 1:
recvFile = open(filename,"ab")
#判断包是否从1开始递增,按顺序接收包
if recvPackNum == recv_pack_num+1:
fileData = recvData[4:]
# 按顺序收到的包就写入文件
recvFile.write(fileData)
recv_pack_num += 1
# 返回确认数据包 两个H为分别两个字节占位符 表示后的4,和收到数据包的编号
ackCmdPack = struct.pack("!HH",4,recv_pack_num)
udpSocket.sendto(ackCmdPack,recvAddr)
#返回的为文件数据,但是字节小于516 ,说明后面没有数据了。传输结束关闭文件
if recvDataLen < 516:
recvFile.close()
print("%s 下载完成" % filename)
break
elif recvCmd == 5:
errorCode = struct.unpack("!H",recvData[2:4])
errorMessage = recvData[4:-1]
print("error code:%s message:%s" % (errorCode,errorMessage.decode('utf-8')))
break
else:
print("未知错误")
break
下载效果

示例用的服务端windows下的绿色软件tftpd32.exe

TFTP协议介绍-python实现tftp客户端的更多相关文章
- H3C TFTP协议介绍
- python网络-TFTP客户端开发(25)
一. TFTP协议介绍 TFTP(Trivial File Transfer Protocol,简单文件传输协议) 是TCP/IP协议族中的一个用来在客户端与服务器之间进行简单文件传输的协议 特点: ...
- Python socket之tftp协议
1. TFTP协议介绍 TFTP(Trivial File Transfer Protocol,简单文件传输协议) 是TCP/IP协议族中的一个用来在客户端与服务器之间进行简单文件传输的协议 特点: ...
- 【转】 基于TFTP协议的远程升级设计
版权声明:本文为博主原创文章,未经博主允许不得转载.联系邮箱:zhzhchang@126.com 说明:由于CSDN博客编辑器对word格式近乎不支持,因此对表格使用了图片方式(最后一个表格未使用图片 ...
- 基于TFTP协议的远程升级设计
说明:因为CSDN博客编辑器对word格式近乎不支持.因此对表格使用了图片方式(最后一个表格未使用图片格式.大家能够看看效果),CSDN博客编辑器上传图片十分不人性化(直接复制图片是不显示的),因此本 ...
- Python的网络编程[2] -> TFTP 协议[0] -> TFTP 的基本理论
TFTP 的基本理论 目录 通信流程 数据报文格式 传输终结 异常处理 数据丢失和超时 TFTP(Trivial File Transfer Protocol,简单文件传输协议)是UDP协议族中的一个 ...
- Python的网络编程[2] -> TFTP 协议[1] -> TFTP 的 Python 实现
TFTP实现 / TFTP Implement 目录 TFTP 的服务器建立过程 TFTP 的客户端建立过程 1 TFTP 的服务器建立过程 服务器建立步骤主要有: (1) 设定服务器IP和 ...
- Python基础教程之udp和tcp协议介绍
Python基础教程之udp和tcp协议介绍 UDP介绍 UDP --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议.UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但 ...
- UNIX网络编程——分析一帧基于UDP的TFTP协议帧
下图是UDP的段格式: 相比TCP段格式,UDP要简单得多,也没啥好说的,需要注意的是UDP数据长度指payload加上首部的长度. 下面分析一帧基于UDP的TFTP协议帧: 以太网首部 0000: ...
随机推荐
- Roslyn+T4+EnvDTE项目完全自动化 (一)
前言 以前做一个金融软件项目,软件要英文.繁体版本,开始甲方弄了好几个月,手动一条一条替换,发现很容易出错,因为有金融专业术语,字符串在不同语义要特殊处理,第三方工具没法使用.最后我用Roslyn写了 ...
- 职场工作方法论:目标管理SMART原则
目标管理由管理学大师彼得·德鲁克在他的著作<管理实践>(The Practice of Management)一书中提出.SMART原则(Specific具体的, Measurable可衡 ...
- SpringCloud微服务实战——搭建企业级开发框架(二十五):实现多租户多平台短信通知服务
目前系统集成短信似乎是必不可少的部分,由于各种云平台都提供了不同的短信通道,这里我们增加多租户多通道的短信验证码,并增加配置项,使系统可以支持多家云平台提供的短信服务.这里以阿里云和腾讯云为例,集成短 ...
- 2017年最有前景的十大IT职业岗位
在IT行业,并不常存在失业的现象,因为目前整个行业存在严重的专业人才供给不足的现象:但同样,想要进入这个行业并牢牢站稳脚跟,你也需要拥有更强于其他行业的竞争力和承受更大的压力.那在行业中,哪些职位更有 ...
- IOI 2020 国家集训队作业
\(\checkmark\) 试题一 完成情况 试题二 完成情况 试题三 完成情况 cf549E cf674G arc103_f \(\checkmark\) cf594E agc034_f agc0 ...
- Perl语言入门14-17
---------第十四章 字符串与排序------------------- index查找子字符串 my $stuff = "howdy world!"; my $where ...
- Linux搭建rsync备份服务器备份
环境: 1台rsync备份服务器,IP:10.0.0.188 1台rsync备份客户端,IP:10.0.0.51 备份数据需注意: 1. 在业务低谷时间进行备份 2. 进行备份限速 一.搭建rsync ...
- Perl if条件判断
Perl 条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 条件判断常用: True #布尔值 not True #布尔值 ! True ...
- 使用input+datalist简单实现实时匹配的可编辑下拉列表-并解决选定后浏览器默认只显示value的可读性问题
问题背景 最近小伙伴提了一个希望提高后台下拉列表可操作性的需求,原因是下拉列表选项过多,每次下拉选择比较费时费力且容易出错,硬着头皮啃了啃前端知识,网上搜寻了一些下拉列表实现的资料,这里总结一下. P ...
- C#筛选项联动,联动筛选
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { FillDep(); } // FillDG(); ...