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代码详解 协议写在程序中的更多相关文章

  1. Native Application 开发详解(直接在程序中调用 ntdll.dll 中的 Native API,有内存小、速度快、安全、API丰富等8大优点)

    文章目录:                   1. 引子: 2. Native Application Demo 展示: 3. Native Application 简介: 4. Native Ap ...

  2. 九、小程序 Redux详解与在小程序中怎么使用(action和reducers)

    什么是Redux ​ Redux我们可以把它理解成一个状态管理器,可以把状态(数据)存在Redux中,以便增.删.改.例如: 从服务器上取一个收藏列表,就可以把取回来的列表数据用Redux管理,多个页 ...

  3. ARM Cortex-M底层技术(2)—启动代码详解

    杂谈 工作了一天,脑袋比较乱.一直想把底层的知识写成一个系列,希望可以坚持下去.为什么要写底层的东西呢?首先,工作用到了这部分内容,最近和内部Flash打交道比较多,自然而然会接触到一些底层的东西:第 ...

  4. BM算法  Boyer-Moore高质量实现代码详解与算法详解

    Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...

  5. Github-karpathy/char-rnn代码详解

    Github-karpathy/char-rnn代码详解 zoerywzhou@gmail.com http://www.cnblogs.com/swje/ 作者:Zhouwan  2016-1-10 ...

  6. 代码详解:TensorFlow Core带你探索深度神经网络“黑匣子”

    来源商业新知网,原标题:代码详解:TensorFlow Core带你探索深度神经网络“黑匣子” 想学TensorFlow?先从低阶API开始吧~某种程度而言,它能够帮助我们更好地理解Tensorflo ...

  7. 基础 | batchnorm原理及代码详解

    https://blog.csdn.net/qq_25737169/article/details/79048516 https://www.cnblogs.com/bonelee/p/8528722 ...

  8. 委托与事件代码详解与(Object sender,EventArgs e)详解

    委托与事件代码详解 using System;using System.Collections.Generic;using System.Text; namespace @Delegate //自定义 ...

  9. 开胃小菜——impress.js代码详解

    README 友情提醒,下面有大量代码,由于网页上代码显示都是同一个颜色,所以推荐大家复制到自己的代码编辑器中看. 今天闲来无事,研究了一番impress.js的源码.由于之前研究过jQuery,看i ...

随机推荐

  1. 安卓Socket开发注意事项

    如果要在安卓app里用到Socket通信,要满足: 1.在写代码的activity里import进Socket相关的包,这个很easy,如果你不知道要import什么包,也可以先不指定,可       ...

  2. 使用pako.js实现gzip的压缩和解压

    poko.js可至Github下载:https://github.com/nodeca/pako 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...

  3. LeetCode5.最长回文子串 JavaScript

    给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab" 注意: &qu ...

  4. Django-rest-framework(二)serializers 使用

    简介 初次见到serializers文件,想必大家都会感到陌生,所以,我们不妨换个词来形容他的作用,那就是django 中的Form,这样是不是感觉熟悉了一点. 实际上,serializers 的作用 ...

  5. 纯 HTML5 APP与原生APP的差距在哪?

    纯 HTML5 APP与原生APP的差距在哪? 写过一些纯H5的APP,虽然开发起来的确很快很舒服,但和原生比起来纯H5APP还是有很多问题,主要聚集在以下几个方面: 1.动画 动画有很多种,比如侧边 ...

  6. 使用第三方《UITableView+FDTemplateLayoutCell》自动计算UITableViewCell高度(Masonry约束)

    直接上代码: 1:先自定义cell .h文件中 #import <UIKit/UIKit.h> #import "LBDNewMsgListModel.h" #impo ...

  7. zepto 基础知识(6)

    101.$.ajax $.ajax(options) 类型:XMLttpRequest 执行Ajax请求.他可能是本地资源,或者通过支持HTTP access control的浏览器 或者通过 JSO ...

  8. SP1716 GSS3 - Can you answer these queries III(单点修改,区间最大子段和)

    题意翻译 nnn 个数, qqq 次操作 操作0 x y把 AxA_xAx​ 修改为 yyy 操作1 l r询问区间 [l,r][l, r][l,r] 的最大子段和 题目描述 You are give ...

  9. oracle约束约束状态和设计习惯

    oracle约束状态有几个项目,会让人迷惑,分别是: enable/disable--是否启用/禁用 validate/invalidate--确认/不确认 deferrable/not deferr ...

  10. pycharm中配置pyspark

    1 下载官网spark-2.1.1-bin-hadoop2.7.tgz(版本自己选择),解压将文件放在了指定路径下,这个文件夹里面有python文件,python文件下还有两个压缩包py4j-some ...