TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP协议族中的一个用来在客户端与服务器之间进行简单文件传输的协议
特点:
1、简单
2、占用资源小
3、适合传递小文件
4、适合在局域网进行传递
5、端口号为69
6、基于UDP实现
当服务器找到需要现在的文件后,会立刻打开文件,把文件中的数据通过TFTP协议发送给客户端
如果文件的总大小较大(比如3M),那么服务器分多次发送,每次会从文件中读取512个字节的数据发送过来
因为发送的次数有可能会很多,所以为了让客户端对接收到的数据进行排序,所以在服务器发送那512个字节数据的时候,会多发2个字节的数据,用来存放序号,并且放在512个字节数据的前面,序号是从1开始的
因为需要从服务器上下载文件时,文件可能不存在,那么此时服务器就会发送一个错误的信息过来,为了区分服务发送的是文件内容还是错误的提示信息,所以又用了2个字节 来表示这个数据包的功能(称为操作码),并且在序号的前面
操作码 | 功能 |
---|---|
1 | 读请求,即下载 |
2 | 写请求,即上传 |
3 | 表示数据包,即DATA |
4 | 确认码,即ACK |
5 | 错误 |
因为udp的数据包不安全,即发送方发送是否成功不能确定,所以TFTP协议中规定,为了让服务器知道客户端已经接收到了刚刚发送的那个数据包,所以当客户端接收到一个数据包的时候需要向服务器进行发送确认信息,即发送收到了,这样的包成为ACK(应答包)
为了标记数据已经发送完毕,所以规定,当客户端接收到的数据小于516(2字节操作码+2个字节的序号+512字节数据)时,就意味着服务器发送完毕了
TFTP数据包格式如下:
---------------------代码案例实现---------------------
1 #coding=utf-8 2 3 #进行对应包的引用 4 from socket import * 5 6 import struct 7 8 import sys 9 10 #创建一个套接字进行网络通信 11 soc =socket(AF_INET,SOCK_DGRAM) 12 13 #获取对应传递的ip地址参数 14 strIp=sys.argv[1] 15 16 #元组,放对应的ip地址和端口号 17 addr=(strIp,69) 18 19 #参数:现在文件的名字 20 strName=sys.argv[2] 21 22 #进行组包,提交给TFTP服务 23 sendData=struct.pack("!H"+str(len(strName))+"sb5sb",1,strName,0,"octet",0) 24 25 #数据的发送 26 soc.sendto(sendData,addr) 27 28 #初始化文件管理对象 29 fil=‘‘ 30 31 #下载后的文件重命名 32 filName=sys.argv[2] 33 34 while True: 35 #接受服务器的相应数据(内容,(ip,端口)) 36 recvData,recvAddr=soc.recvfrom(1024) 37 38 #对接受的数据进行处理 39 opkey=struct.unpack("!HH",recvData[:4]) 40 41 print(opkey) 42 43 #变量存储序号 44 pNum=opkey[1] 45 46 #3判断,从服务器上下载的数据 47 if opkey[0]==3: 48 #第一次数据传递时,进行对应的文件的创建 49 if pNum==1: 50 fil=open(filName,"w") 51 #数据的写入 52 fil.write(recvData[4:]) 53 54 if len(recvData)<516: 55 56 fil.close() 57 print("下载完成!") 58 break 59 60 #5判断,TFTP服务器出现错误 61 if opkey[0]==5: 62 print("运行错误!") 63 break 64 65 #组包 66 ackData=struct.pack("!HH",4,pNum) 67 68 soc.sendto(ackData,recvAddr) 69 soc.close()
模拟实现TFTP下载客户端
---------------------附件struct表--------------------
时间: 2024-10-07 05:03:05