8 TFTP代码详解 协议写在程序中
1.版本1:发送请求
# -*- coding:utf-8 -*- import struct
from socket import * #0. 获取要下载的文件名字:
downloadFileName = raw_input("请输入要下载的文件名:") #1.创建socket
udpSocket = socket(AF_INET, SOCK_DGRAM) requestFileData = struct.pack("!H%dsb5sb"%len(downloadFileName), 1, downloadFileName, 0, "octet", 0) #2. 发送下载文件的请求
udpSocket.sendto(requestFileData, ("192.168.119.215", 69))
2.版本2:回复ack
# -*- coding:utf-8 -*- import struct
from socket import * #0. 获取要下载的文件名字:
downloadFileName = raw_input("请输入要下载的文件名:") #1.创建socket
udpSocket = socket(AF_INET, SOCK_DGRAM) requestFileData = struct.pack("!H%dsb5sb"%len(downloadFileName), 1, downloadFileName, 0, "octet", 0) #2. 发送下载文件的请求
udpSocket.sendto(requestFileData, ("192.168.119.215", 69)) #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])
3.版本3:while True 循环
# -*- coding:utf-8 -*- import struct
from socket import *
import time
import os def main(): #0. 获取要下载的文件名字:
downloadFileName = raw_input("请输入要下载的文件名:") #1.创建socket
udpSocket = socket(AF_INET, SOCK_DGRAM)
requestFileData = struct.pack("!H%dsb5sb"%len(downloadFileName), 1, downloadFileName, 0, "octet", 0) #2. 发送下载文件的请求
udpSocket.sendto(requestFileData, ("192.168.119.215", 69)) 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]) time.sleep(0.1) if __name__ == '__main__':
main()
4.版本4:跳出循环
# -*- coding:utf-8 -*- import struct
from socket import *
import time
import os def main(): #0. 获取要下载的文件名字:
downloadFileName = raw_input("请输入要下载的文件名:") #1.创建socket
udpSocket = socket(AF_INET, SOCK_DGRAM)
requestFileData = struct.pack("!H%dsb5sb"%len(downloadFileName), 1, downloadFileName, 0, "octet", 0) #2. 发送下载文件的请求
udpSocket.sendto(requestFileData, ("192.168.119.215", 69)) flag = True #表示能够下载数据,即不擅长,如果是false那么就删除
num = 0
f = open(downloadFileName, "w") 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]) time.sleep(0.1) if len(recvData)<516:
break if __name__ == '__main__':
main()
5.版本5:优化版本,文件不存在
# -*- coding:utf-8 -*- import struct
from socket import *
import time
import os def main(): #0. 获取要下载的文件名字:
downloadFileName = raw_input("请输入要下载的文件名:") #1.创建socket
udpSocket = socket(AF_INET, SOCK_DGRAM) requestFileData = struct.pack("!H%dsb5sb"%len(downloadFileName), 1, downloadFileName, 0, "octet", 0) #2. 发送下载文件的请求
udpSocket.sendto(requestFileData, ("192.168.119.215", 69)) flag = True #表示能够下载数据,即不擅长,如果是false那么就删除
num = 0
f = open(downloadFileName, "w") 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()
6.版本6:第二种参考程序
#coding=utf-8 from socket import *
import struct
import sys if len(sys.argv) != 2:
print('-'*30)
print("tips:")
print("python xxxx.py 192.168.1.1")
print('-'*30)
exit()
else:
ip = sys.argv[1] # 创建udp套接字
udpSocket = socket(AF_INET, SOCK_DGRAM) #构造下载请求数据
cmd_buf = struct.pack("!H8sb5sb",1,"test.jpg",0,"octet",0) #发送下载文件请求数据到指定服务器
sendAddr = (ip, 69)
udpSocket.sendto(cmd_buf, sendAddr) p_num = 0 recvFile = '' while True:
recvData,recvAddr = udpSocket.recvfrom(1024) recvDataLen = len(recvData) # print recvAddr # for test # print len(recvData) # for test cmdTuple = struct.unpack("!HH", recvData[:4]) # print cmdTuple # for test cmd = cmdTuple[0]
currentPackNum = cmdTuple[1] if cmd == 3: #是否为数据包 # 如果是第一次接收到数据,那么就创建文件
if currentPackNum == 1:
recvFile = open("test.jpg", "a") # 包编号是否和上次相等
if p_num+1 == currentPackNum:
recvFile.write(recvData[4:]);
p_num +=1
print '(%d)次接收到的数据'%(p_num) ackBuf = struct.pack("!HH",4,p_num) udpSocket.sendto(ackBuf, recvAddr)
# 如果收到的数据小于516则认为出错
if recvDataLen<516:
recvFile.close()
print '已经成功下载!!!'
break elif cmd == 5: #是否为错误应答
print "error num:%d"%currentPackNum
break udpSocket.close()
8 TFTP代码详解 协议写在程序中的更多相关文章
- Native Application 开发详解(直接在程序中调用 ntdll.dll 中的 Native API,有内存小、速度快、安全、API丰富等8大优点)
文章目录: 1. 引子: 2. Native Application Demo 展示: 3. Native Application 简介: 4. Native Ap ...
- 九、小程序 Redux详解与在小程序中怎么使用(action和reducers)
什么是Redux Redux我们可以把它理解成一个状态管理器,可以把状态(数据)存在Redux中,以便增.删.改.例如: 从服务器上取一个收藏列表,就可以把取回来的列表数据用Redux管理,多个页 ...
- ARM Cortex-M底层技术(2)—启动代码详解
杂谈 工作了一天,脑袋比较乱.一直想把底层的知识写成一个系列,希望可以坚持下去.为什么要写底层的东西呢?首先,工作用到了这部分内容,最近和内部Flash打交道比较多,自然而然会接触到一些底层的东西:第 ...
- BM算法 Boyer-Moore高质量实现代码详解与算法详解
Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...
- Github-karpathy/char-rnn代码详解
Github-karpathy/char-rnn代码详解 zoerywzhou@gmail.com http://www.cnblogs.com/swje/ 作者:Zhouwan 2016-1-10 ...
- 代码详解:TensorFlow Core带你探索深度神经网络“黑匣子”
来源商业新知网,原标题:代码详解:TensorFlow Core带你探索深度神经网络“黑匣子” 想学TensorFlow?先从低阶API开始吧~某种程度而言,它能够帮助我们更好地理解Tensorflo ...
- 基础 | batchnorm原理及代码详解
https://blog.csdn.net/qq_25737169/article/details/79048516 https://www.cnblogs.com/bonelee/p/8528722 ...
- 委托与事件代码详解与(Object sender,EventArgs e)详解
委托与事件代码详解 using System;using System.Collections.Generic;using System.Text; namespace @Delegate //自定义 ...
- 开胃小菜——impress.js代码详解
README 友情提醒,下面有大量代码,由于网页上代码显示都是同一个颜色,所以推荐大家复制到自己的代码编辑器中看. 今天闲来无事,研究了一番impress.js的源码.由于之前研究过jQuery,看i ...
随机推荐
- [转]查找问题的利器 - Git Bisect
转自:http://gitbook.liuhui998.com/5_4.html 假设你在项目的'2.6.18'版上面工作, 但是你当前的代码(master)崩溃(crash)了. 有时解决这种问题的 ...
- JQuery前端技术记录
[Jquery-leearning notes-2015]by lijun 1 Jquery是javascript实现的库,目标在于改变web应用的高交互性的方式. 其不唐突性:样式(.css). ...
- Android进阶笔记13:ListView篇之ListView刷新显示(全局 和 局部)
一.ListView内容变化后,动态刷新的步骤(全局刷新): (1)更新适配器Adapter数据源:(不要使用匿名内部类) (2)调用适配器Adapter的刷新方法notifyDataSetChang ...
- ueditor1.2.6图片被压缩的解决办法
修改文件路径: ueditor\dialogs\image\image.html 修改数值:
- 【luogu P2385 青铜莲花池】 题解
题目链接:https://www.luogu.org/problemnew/show/P2385 莲花池什么的最漂亮啦! 最近刷了两天搜索= =我搜索一直是弱菜 直接套bfs #include < ...
- 【luogu P3379 最近公共祖先】 模板
题目链接:https://www.luogu.org/problemnew/show/P3379 倍增求lca,先存下板子,留个坑以后再填讲解. in 5 5 43 12 45 11 42 43 23 ...
- 在CentOs6.5下安装Python2.7.6和Scrapy
总在网上看大家的安装教程,这回自己也贡献一份!!! 和民航大学合作项目,去给人家装环境,连简单的Scrapy都没装上,虽然有对方硬件设施坑爹的因素,但主要还是自己准备不充分. 一份好的安装文档应该是可 ...
- ContentProvider 、 ContentResolver 、 ContentObserver
说说ContentProvider . ContentResolver . ContentObserver 之间的关系**a. ContentProvider 内容提供者,用于对外提供数据 b. Co ...
- Golang 字符串转URLCode
Golang 字符串转URLCode 最近因调用gitlab API,在生成某些字符串的时候直接请求 gitlab API 失败, url如下: keysURL := "http://192 ...
- 【2018 ICPC亚洲区域赛沈阳站 L】Tree(思维+dfs)
Problem Description Consider a un-rooted tree T which is not the biological significance of tree or ...