tftp协议给服务器上传数据,TFTP连接过程详解
概述
TFTP,全称是 Trivial File Transfer Protocol(简单文件传输协议),基于 UDP
实现,该协议简单到只能从远程服务器读取数据或向远程服务器上传数据。TFTP
有三种模式:netascii,这是8位的ASCII码形式;另一种是octet,这是8位源数据类型;最后一种 mail
已经不再支持,它将返回的数据直接返回给用户而不是保存为文件。
虽然 TFTP 不具备通常的 FTP 的许多功能,但是学习 TFTP
可以帮助我们了解网络通信协议的基本工作过程和原理,对后续学习更加复杂的协议有很大的帮助作用。
首先看一下 TFTP 的包的类型,TFTP 有 5 种类型的包:
建立连接
默认情况下,作为 TFTP 服务器的主机 A 会监听 69 端口,当作为客户端的主机 B 想要下载或上传文件时,会向主机 A
的 69 端口发送包含读文件(下载)请求或写文件(上传)请求的数据包。主机 A
收到读写请求后,会打开另外一个随机的端口,通过这个端口向主机 B 发送确认包、数据包或者错误包。
下载
客户端向服务器的 69 端口(通常情况下)发送一个读请求,服务器收到这个读请求以后,会打开另外一个随机的端口(假设端口号是
59509),然后在它默认的路径下寻找这个文件,找到这个文件以后,每次读入文件的 512 个字节,通过端口 59509 将这 512
个字节放入数据包中发送给客户端,数据包中还包含了操作码和数据块的编号,块编号从 1 开始计数;客户端收到数据包以后,会向服务器的
59509 端口发送一个确认包,里面包含了它收到的数据包的块编号;服务器收到确认包以后,继续发送文件的下一个 512
个字节。
如此循环往复,直到文件的末尾,最后一个数据包的数据块的大小会小于 512
个字节,这时服务器就认为传输已经结束,等他接收到这最后一个数据包的确认包之后就会主动关闭连接。而客户端收到这个小于 512
个字节的数据包后也认为传输已经结束,发送完确认包之后也会关闭连接。
也许会有一种极端情况,就是文件的大小正好是 512 字节的倍数,这样的话,最后一个数据包的大小也是 512
个字节,这时服务器发送完包含文件数据的数据包以后,还会额外发送一个包含 0
字节的数据包,作为最后一个数据包,这样就可以保证客户端收到的最后一个数据包的大小总是小于 512
个字节的。也就是说,对于客户端而言,只要它收到的数据包的大小小于 512 个字节,它就认为传输已经结束,它就会关闭连接。
下面是 TFTP 下载图示:
上传
客户端向服务器的 69 端口(通常情况下)发送一个写请求,服务器收到这个写请求以后,会打开另外一个随机的端口(假设端口号是
59509),向客户端发送一个确认包,其中块编号是
0,以此来告诉客户端自己已经准备好接收文件,并且告诉客户端自己接收文件的端口号。
然后客户端就开始向服务器的 59509
端口发送数据包,服务器收到数据包后向客户端发送确认包,直到整个文件发送完毕。这个过程和下载是一样的,只不过双方的角色互换了,客户端成了发数据的一方,而服务器是接收数据的一方。
下面是 TFTP 上传图示:
错误机制
TFTP 提供了一些错误机制,若出现错误,服务器会向客户端发送 ERROR 包,包格式如下:
前两个字节是操作码,值是 5,代表这是一个 ERROR
包。接下来两个字节是差错码,代表了错误的类型,下面是不同的差错码对应的错误类型:
差错码 含义
1 File not found. (文件未找到,服务器未找到下载请求中指定的文件)
2 Access violation. (访问违规,程序对于服务器的默认路径没有写权限导致的)
3 Disk full or allocation exceeded.
(磁盘已满或超出分配,上传文件时可能会出现这个错误)
4 Illegal TFTP operation. (非法的 TFTP 操作,服务器无法识别 TFTP
包中的操作码)
5 Unknown transfer ID. (未知的传输标识)
6 File already exists. (文件已存在,要上传的文件已存在于服务器中)
7 No such user. (没有该用户)
接下来的 n 个字节用于存放错误信息,这部分可以由程序员自己决定存放什么信息。最后一个字节是 0,用来标识结尾。
代码实现
下面以下载文件为例,用 Python 实现一个 TFTP 的客户端。
实验环境
Windows 10
VMware 15,里面安装了 Windows 10 操作系统的虚拟机
Python 3.7
tftpd64(一个支持 TFTP 协议的软件,安装到 Windows 10 虚拟机里面作为服务器)
下面是 Python 代码:
#filename: tftp_client_download.py
import struct
from socket import *
'''
第一个参数是要下载的文件名,类型是字符串
第二个参数是服务器的IP地址和端口号,类型是元组,
元组中有两个元素,第一个元素是IP地址,类型是字符串,第二个元素是端口号,类型是整数。
比如:('192.168.1.2', 69)
'''
def download(file_name, servAddr):
file_name_byte_array =
file_name.encode('gb2312')
#组包,octet
代表TFTP协议的一种模式
sendData =
struct.pack('!H'+str(len(file_name_byte_array))+'sb5sb',
1, file_name_byte_array, 0,
b'octet', 0)
udpSocket =
socket(AF_INET, SOCK_DGRAM)
udpSocket.sendto(sendData, servAddr)
newFile =
open(file_name, 'wb')
while True:
#等待接收数据
recvInfo = udpSocket.recvfrom(1024)
#1024表示本次接受的最大字节数
transPort = recvInfo[1][1] #传输端口
data = recvInfo[0] #TFTP数据包的字节流
len_data = len(data)
result = struct.unpack("!H", data[:2]) #解包
opcode = result[0] #获取操作码
if opcode == 3: #如果操作码是3,说明是DATA包
result =
struct.unpack('!H'+str(len_data-4)+'s', data[2:len_data])
block =
result[0] #获取块编号
fileStream
= result[1] #文件字节流
newFile.write(fileStream)
#向服务器发送一个确认包
ackInfo =
struct.pack('!HH', 4, block)
udpSocket.sendto(ackInfo, (servAddr[0], transPort))
if
len(fileStream) < 512:
break
elif opcode == 5: #如果操作码是5,说明是ERROR包
result =
struct.unpack('!H'+str(len_data-5)+'s', data[2:len_data-1])
print('传输出现异常!')
print(result[1].decode('gb2312')) #输出错误信息
break
newFile.close()
udpSocket.close()
def main():
#服务器的IP地址
serverIP =
'192.168.133.135'
#服务器监听端口,默认是69,这只是用来监听客户端请求的端口,另外还有操作系统随机分配的用来传输文件的端口
serverPort =
69
servAddr = (serverIP,
serverPort)
filename =
'zoro.png'
download(filename,
servAddr)
if __name__ == '__main__':
main()
实验过程
在虚拟机中打开 tftpd64,选择 Tftp Server 选项卡,点击右上角的 Browse
按钮,选择一个主目录,将来收到下载请求的时候,程序会在你选择的这个目录里查找请求下载的文件。
查看一下虚拟机的IP地址,将上面 Python 代码中的服务器 IP 地址改成虚拟机的IP地址,在真实的电脑中运行
Python 代码。
如图所示,若没有出现任何错误提示,就文件说明下载成功,文件已经下载到了当前目录下。
延伸
在代码运行过程中,还可以打开 Wireshark,抓取 TFTP 包,查看其具体内容。
tftp协议给服务器上传数据,TFTP连接过程详解相关推荐
- 上传本地代码到gitHub过程详解
转自:链接 1.注册github账号. 2.创建个人的github仓库,如图, 或者也可以进入个人中心去创建, 还可以直接点击右上角的""+""添加, 3.创建 ...
- sap服务器文件上传,服务器上传数据sap
服务器上传数据sap 内容精选 换一换 通常在将数据导入数据库前,即将入库的数据已经在相关主机上了.我们称这种保存着待入库数据的服务器为数据服务器.此时,只需检测以确认数据服务器和GaussDB(DW ...
- linux上连接ftp服务器,linux下lftp连接ftp服务器进行上传与下载的方法详解
摘要 腾兴网为您分享:linux下lftp连接ftp服务器进行上传与下载的方法详解,中英翻译,中建在线,掌上看家,银行帮等软件知识,以及微信一键转发工具,小学英语冀教版,正是在下表情包,易问电信,万能 ...
- python代码图片头像_Flask 上传自定义头像的实例详解
Flask Web 开发这本书基本上做完了,后面还需要温习,但是自己做的博客总觉得简陋了点,所以,在动脑子开发新功能 今天想到最基本的功能,自定义头像 那这样的功能,设计到2大基本功能块 1:如何进行 ...
- python接入excel_使用python将excel数据导入数据库过程详解
因为需要对数据处理,将excel数据导入到数据库,记录一下过程. 使用到的库:xlrd 和 pymysql (如果需要写到excel可以使用xlwt) 直接丢代码,使用python3,注释比较清楚. ...
- 张小白的渗透之路(五)——上传漏洞及解析漏洞详解
前言 web应用程序通常会有文件上传的功能,例如在BBS发布图片.在个人网站发布压缩包,只要web应用程序允许上传文件,就有可能存在文件上传漏洞. 上传漏洞与sql注射相比,风险更大,如果web应用程 ...
- java上传下载_Java文件上传与文件下载实现方法详解
本文实例讲述了Java文件上传与文件下载实现方法.分享给大家供大家参考,具体如下: Java文件上传 数据上传是客户端向服务器端上传数据,客户端向服务器发送的所有请求都属于数据上传.文件上传是数据上传 ...
- Linux 中 3 个文件打包上传和下载相关命令详解
tar 命令 通过 SSH 访问服务器,难免会要用到压缩,解压缩,打包,解包等,这时候tar 命令就是必不可少的一个功能强大的工具.Linux 中最流行的tar是麻雀虽小,五脏俱全,功能强大. 使用t ...
- linuxsz隐藏文件_linux中rz上传、sz下载命令详解
rz,sz是Linux/Unix同Windows进行ZModem文件传输的命令行工具. 使用前提: 首先,你的Linux端(CentOS, Ubuntu)需要安装rz/sz命令,也就是 lszrz 包 ...
- 网络安全与渗透:文件上传漏洞,一文详解(十)此生无悔入华夏,男儿何不带吴钩
中华人民共和国网络安全法 阅读本文前,请熟读并遵守中华人民共和国网络安全法: http://gkhy.jiujiang.gov.cn/zwgk_228/jc/zcwj/202006/P02020061 ...
最新文章
- 2008秋-计算机软件基础-第四章习题参考答案 P131 ,习题6之一
- 人均奖金300万,2021年“科学探索奖”名单揭晓:高会军周昆上榜,女性获奖人8位创纪录...
- KeyMob移动广告聚合平台:类似于房地产中介
- 解决iptables和vsftpd设置的问题
- 《超低延时直播白皮书》已发布,推动直播延时降低90%以上
- wine运行exe程序只出现了一个黑色长方形
- 处女座男生颜值测试软件,颜值在线又绅士的星座男(图)
- java 单元测试技巧_其他一些单元测试技巧
- cocos2d-x自制工具02:AnimatePacker v1.1beta发布!!~!
- 自然语言处理——用逻辑回归来实现情绪识别
- python颜色识别_python颜色识别
- 如何速成java_极*Java速成教程 - (2)
- 问道虚拟机服务器地址,【问道1.60.0905】虚拟机手工启动服务端+配套客户端+配套工具+充值注册软件+启动教程...
- win7电脑便签怎么弄
- NPOI SetRowBreak 插入分页符无用
- Matlab中的图怎样插入Word效果最好
- 异构网络-元图、知识图谱
- 【渝粤题库】陕西师范大学165205 组织设计与人力资源规划 作业(专升本)
- 计算机游戏翻译,百度翻译电脑版
- 32岁学python有前途吗_Python发展前景如何?学习Python游戏开发有前途吗?