python高级进阶_36_熟悉tftp协议代码模拟下载过程

代码如下:

# -*- coding:utf-8 -*-

import struct
from socket import *
import time
import os

def main():


	#0. 获取要下载的文件名字:
	downloadFileName = input("请输入要下载的文件名:")

	#1.创建socket
	udpSocket = socket(AF_INET, SOCK_DGRAM)

	requestFileData = struct.pack("!H%dsb5sb"%len(downloadFileName), 1, bytes(downloadFileName.encode('utf-8')), 0, b"octet", 0)

	#2. 发送下载文件的请求tetes
	udpSocket.sendto(requestFileData, ("127.0.0.1", 69))

	flag = True #表示能够下载数据,即不擅长,如果是false那么就删除
	num = 0
	f = open(downloadFileName, "bw")

	while True:
		#3. 接收服务发送回来的应答数据
		responseData = udpSocket.recvfrom(1024)

		# print(responseData)
		recvData, serverInfo = responseData

		opNum = struct.unpack("!H", recvData[:2])

		packetNum = struct.unpack("!H", recvData[2:4])

		print(packetNum[0])

		# print("opNum=%d"%opNum)
		# print(opNum)

		# if 如果服务器发送过来的是文件的内容的话:
		if opNum[0] == 3: #因为opNum此时是一个元组(3,),所以需要使用下标来提取某个数据
			

			#计算出这次应该接收到的文件的序号值,应该是上一次接收到的值的基础上+1
			num = num + 1

			# 如果一个下载的文件特别大,即接收到的数据包编号超过了2个字节的大小
			# 那么会从0继续开始,所以这里需要判断,如果超过了65535 那么就改为0
			if num==65536:
				num = 0

			# 判断这次接收到的数据的包编号是否是 上一次的包编号的下一个
			# 如果是才会写入到文件中,否则不能写入(因为会重复)
			if num == packetNum[0]:
				# 把收到的数据写入到文件中
				f.write(recvData[4:])
				num = packetNum[0]

			#整理ACK的数据包
			ackData = struct.pack("!HH", 4, packetNum[0])
			udpSocket.sendto(ackData, serverInfo)

		elif opNum[0] == 5:
			print("sorry,没有这个文件....")
			flag = False

		# time.sleep(0.1)

		if len(recvData)<516:
			break

	if flag == True:
		f.close()
	else:
		os.unlink(downloadFileName)#如果没有要下载的文件,那么就需要把刚刚创建的文件进行删除

if __name__ == '__main__':
	main()

首先要 打开服务器端, 可以下载 tftpd32 这个软件。

在这里插入图片描述
后边理解看我注释就行了。 不懂,可以留言,我补充 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值