TFTP下载器
1.环境搭建
使用tftpd32搭建本地Tftp服务器,将文件路径选择到指定位置(当前位置为桌面)
将文件1.png放在桌面位置。
2.实现代码
from socket import *
import struct
filename = '1.png'#存放即将下载的文件名
server_ip = '192.168.1.101'#存放服务器所在ip地址
send_data = struct.pack('!H%dsb5sb' % len(filename),1,filename.encode(),0,'octet'.encode(),0)#由于filename长度不固定,用% len(filename) %d
s = socket(AF_INET,SOCK_DGRAM)
s.sendto(send_data,(server_ip,69))
f = open(filename,'ab')#创建空文件
while True:
recv_data = s.recvfrom(1024)# 接收数据( ,( ) )
caozuoma,ack_num = struct.unpack('!HH',recv_data[0][:4])#获取数据块编号
rand_port = recv_data[1][1]#获取服务器随机端口
if int(caozuoma) == 5:
print('文件不存在')
break
print("操作码:%d,ACK: %d,服务器随机端口:%d,数据长度:%d"%(caozuoma,ack_num,rand_port,len(recv_data[0][4:])))
f.write(recv_data[0][4:])#将数据写入
if len(recv_data[0]) < 516:
break
ack_data = struct.pack("!HH", 4, ack_num) # 发送确认码
s.sendto(ack_data,(server_ip,rand_port))#回复ACK确认包
send_data = struct.pack(‘!H%dsb5sb’ % len(filename),1,filename.encode(),0,‘octet’.encode(),0)
由于filename长度不固定,表示% len(filename) 个字节数
这里构建读写请求
caozuoma,ack_num = struct.unpack(‘!HH’,recv_data[0][:4])
用recv_data[0]的前两个字节表示操作码,第三第四字节表示块编号
ack_data = struct.pack(“!HH”, 4, ack_num)
s.sendto(ack_data,(server_ip,rand_port))
发送ACK确认码