[转载] Python中TFTP的理解

参考链接: Python中的打包pack和拆包unpack参数

Num01–>TFTP协议介绍 

 

 TFTP(Trivial File Transfer Protocol,简单文件传输协议) 

 是TCP/IP协议族中的一个用来在客户端与服务器之间进行简单文件传输的协议 

 特点: 

 1,简单  2,占用资源小  3,适合传递小文件  4,适合在局域网进行传递  5,端口号为69  6,基于UDP实现 

 

Num02–>TFTP下载过程 

 

 TFTP服务器默认监听69号端口 

 当客户端发送“下载”请求(即读请求)时,需要向服务器的69端口发送 

 服务器若批准此请求,则使用一个新的、临时的 端口进行数据传输 

 

 

 

 当服务器找到需要现在的文件后,会立刻打开文件,把文件中的数据通过TFTP协议发送给客户端 

 如果文件的总大小较大(比如3M),那么服务器分多次发送,每次会从文件中读取512个字节的数据发送过来 

 因为发送的次数有可能会很多,所以为了让客户端对接收到的数据进行排序,所以在服务器发送那512个字节数据的时候,会多发2个字节的数据,用来存放序号,并且放在512个字节数据的前面,序号是从1开始的 

 因为需要从服务器上下载文件时,文件可能不存在,那么此时服务器就会发送一个错误的信息过来,为了区分服务发送的是文件内容还是错误的提示信息,所以又用了2个字节 来表示这个数据包的功能(称为操作码),并且在序号的前面 

 

操作码     功能

 1      读请求,即下载

 2      写请求,即上传

 3      表示数据包,即DATA

 4      确认码,即ACK

 5      错误 

 

 因为udp的数据包不安全,即发送方发送是否成功不能确定,所以TFTP协议中规定,为了让服务器知道客户端已经接收到了刚刚发送的那个数据包,所以当客户端接收到一个数据包的时候需要向服务器进行发送确认信息,即发送收到了,这样的包成为ACK(应答包) 

 为了标记数据已经发送完毕,所以规定,当客户端接收到的数据小于516(2字节操作码+2个字节的序号+512字节数据)时,就意味着服务器发送完毕了 

 

Num03–>TFTP数据包的格式 

 

Num04–>TFTP客户端案例编写 

#! /usr/bin/env python3

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

 

from socket import *

import struct #为了实现打包struct.pack()和拆包struct.unpack()数据

import sys

 

# python3 05-xx.py 192.168.105.125 bb.jpg

def main():

 

    if len(sys.argv) < 3:

        sys.exit('usage : python3  %s ip filename' % sys.argv[0])

 

    #server_ip = '192.168.105.125'

    #file_name = 'bb.jpg'

 

    server_ip = sys.argv[1]

    file_name = sys.argv[2]

 

    udp_socket = socket(AF_INET, SOCK_DGRAM)

    server_addr = (server_ip,69)

 

    #  打包数据

    # !表示网络字节序,H表示2bytes无符号整数,

    #  5s表示长度为5字符串

    #  B表示1byte的无符号整数

    fmt = '!H%dsB5sB' % len(file_name)

    send_data = struct.pack(fmt,1,file_name.encode() ,0,b'octet',0)

    #send_data = struct.pack(fmt,1,file_name ,0,b'octet',0)

 

    udp_socket.sendto(send_data,server_addr)

 

    f =  None # 文件对象

    #上一次blockNum

    lastBlockNum = 0

 

    # 循环接收和应答

    while True:

        recv_data,peer_addr = udp_socket.recvfrom(1024)

        # 拆包数据

        opcode,blockNum = struct.unpack('!HH',recv_data[:4])

 

        if opcode == 3: # 表示数据包

            # 写入文件

            # 1打开文件

            # 第一次收到服务器发送数据包

            if blockNum == 1: 

                f = open(file_name,'wb')

 

            # 拆出数据

            data_fmt = '!%ds' % (len(recv_data) - 4)

            data_content = struct.unpack(data_fmt, recv_data[4:])

 

            # 写入文件之前判断写过没有

            # if 这一次blockNum == 上一次blockNum + 1

            if lastBlockNum + 1 == blockNum:

                #print(data_content[0])

                f.write(data_content[0]) # 拆出来是元组,bytes对象,write时候需要str字符串

 

            # 打包应答数据

            ack_data = struct.pack('!HH',4,blockNum)

            udp_socket.sendto(ack_data,peer_addr) # 不能再给server_addr,因为端口号变了

 

            # 当应答完毕,更新lastBlockNum

            lastBlockNum = blockNum

 

            # 如果数据长度小于 2 + 2 + 512 传输结束

            if len(recv_data) < 516:

                print('over')

                f.close()

                break

        elif opcode == 5:# 出错

            err_num = blockNum

            # 拆出错误信息

            fmt = "!%ds" % (len(recv_data) - 5)

            err_msg = struct.unpack(fmt,recv_data[4:-1])

            print('出错信息:%s' % err_msg)

            break

 

if __name__ == "__main__":

    main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/540565.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

gn fast-gn_GN的完整形式是什么?

gn fast-gnGN&#xff1a;晚安 (GN: Good Night) GN is an abbreviation of "Good Night". GN是“ Good Night”的缩写 。 It is an expression, which is commonly used in messaging or chatting on social media networking sites like Facebook, Yahoo Messenge…

从零开始编写自己的C#框架(27)——什么是开发框架

前言 做为一个程序员&#xff0c;在开发的过程中会发现&#xff0c;有框架同无框架&#xff0c;做起事来是完全不同的概念&#xff0c;关系到开发的效率、程序的健壮、性能、团队协作、后续功能维护、扩展......等方方面面的事情。很多朋友在学习搭建自己的框架&#xff0c;很多…

[转载] Python 递归 深入理解递归 Python递归剖析,绝对让你看懂!

参考链接&#xff1a; Python | print()中的结束参数 目录 递归剖析 递归的两个过程 return 返回值 详解 递归思路二分法和递归尾递归递归练习题 递归剖析 递归真的很重要&#xff0c;之前学的时候&#xff0c;学的一知半解&#xff0c;以为真正了解&#xff0c;每次想到递归…

laravel 项目迁移_在Laravel迁移

laravel 项目迁移Before moving forward we need to know some facts about it, 在继续前进之前&#xff0c;我们需要了解一些事实&#xff0c; Resources: In these directories, we have already a js, lang, sass and view page. Where, sass and js file holf their uncom…

Python之list对应元素求和

本次分享将讲述如何在Python中对多个list的对应元素求和&#xff0c;前提是每个list的长度一样。比如&#xff1a;a[1,2,3], b[2,3,4], c[3,4,5], 对a,b,c的对应元素求和&#xff0c;输出应为[6,9,12].    方法一&#xff1a;   直接求解&#xff0c;按照对应元素相加的…

[转载] Python中str跟int的转换

参考链接&#xff1a; Python中的类型转换 字符串str转换成int: int_value int(str_value) int转换成字符串str: str_value str(int_value) a100 b666 #int转str类型 print(int转str类型) print(int转str&#xff1a; str(a)) #str转int类型 print(str转int类型…

ot协议是什么_OT的完整形式是什么?

ot协议是什么OT&#xff1a;主题外 (OT: Off Topic) OT is an abbreviation of "Off Topic". OT是“ Off Topic”的缩写 。 It is an expression, which is commonly used in Gmail or messaging platform. It shows that the email that has been sent is irrelev…

[转载] python中字符串编码形式及其所占字节

参考链接&#xff1a; Python中的字节对象与字符串 1.常见字符串编码错误 在使用Python读文件时经常遇到编码问题引起的错误&#xff0c;比如&#xff1a; UnicodeDecodeError: gbk codec cant decode byte 0x80 in position 30: illegal multibyte sequence 遇到这种异…

[AtCoder-ARC073F]Many Moves

题目大意&#xff1a;   有一排n个格子和2枚硬币。   现在有q次任务&#xff0c;每一次要你把其中一枚硬币移到x的位置上&#xff0c;移动1格的代价是1。   两枚硬币不能同时移动&#xff0c;任务必须按次序完成。   现在告诉你两枚硬币初始状态所在的位置a和b&#xf…

ScalavsKotlin

Is Scala better that Kotlin? No..., Is Kotlin better than Scala? No... Scala比Kotlin更好吗&#xff1f; 不...&#xff0c;Kotlin胜过Scala吗&#xff1f; 没有... Both programming languages have their own profits and are for a specific set of development. It…

工业智能相机与基于PC的机器视觉的区别比较

随着科技的日渐成熟&#xff0c;机器视觉得到了飞速发展。由于嵌入式技术的发展,近几年智能相机性能显著提高&#xff0c;越来越多必须依赖于PC处理的应用开始向智能相机平台倾斜。低成本、高可靠性及易于安装维护等优势&#xff0c;使得机器视觉在制造业上的规模性应用越来越普…

[转载] python skimage在图像处理中的用法

参考链接&#xff1a; 在Python中打印单变量和多变量 基于python脚本语言开发的数字图片处理包&#xff0c;比如PIL,Pillow, opencv, scikit-image等。 PIL和Pillow只提供最基础的数字图像处理&#xff0c;功能有限&#xff1b;opencv实际上是一个c库&#xff0c;只是提供了py…

scala元组 数组_Scala中的数组

scala元组 数组Scala中的数组 (Arrays in Scala) An array is a linear data structure with a fixed number of elements. It is a collection that stores a fixed number Arrays in Scalf elements of the same datatype. In Scala, an array is 0 indexed, i.e. the first …

OpenStack —— DevStack一键自动化安装

一、DevStack介绍Devstack目前是支持Ubuntu16.04和CentOS 7&#xff0c;而且Devstack官方建议使用Ubuntu16.04&#xff0c;所以我们使用Ubuntu 16.04进行安装。默认无论是Devstack和OpenStack&#xff0c;都是采用Master的代码进行安装&#xff0c;这样经常会出现&#xff0c;今…

[转载] Python学习笔记——运维和Shell

参考链接&#xff1a; 在C / C&#xff0c;Python&#xff0c;PHP和Java中交换两个变量 目录 什么是运维 运维第一工具-shell编程 shell历史 执行脚本 基本语法 Shell脚本语法 条件测试&#xff1a;test [ if/then/elif/else/fi case/esac for/do/done …

scala java混合_Scala特性混合

scala java混合Scala | 特性混合 (Scala | Trait Mixins ) In Scala, the number of traits can be extended using a class or an abstract class. This is known as Trait Mixins. For extending, only traits, the blend of traits, class or abstract class are valid. If …

Scala铸造

Scala中的类型 (Types in Scala) Type also know as data type tells the compiler about the type of data that is used by the programmer. For example, if we initialize a value or variable as an integer the compiler will free up 4 bytes of memory space and it wi…

/ 卡路里_最大卡路里

/ 卡路里Problem statement: 问题陈述&#xff1a; Shivang is very foodie but he has a diet plan. He has an array of elements indicating the calorie of food he can consume on that day. In his diet plan, he can’t eat on for three consecutive days. But since …

[转载] Python类中的私有变量和公有变量

参考链接&#xff1a; Python中的私有变量 我们这里就直奔主题&#xff0c;不做基础铺垫&#xff0c;默认你有一些Python类的基础&#xff0c;大家在看这篇博客的时候&#xff0c;如果基础知识忘了&#xff0c;可以去菜鸟教程 从一个简单的类开始 class A(): #定义一…

OpenCV探索之路(二十五):制作简易的图像标注小工具

搞图像深度学习的童鞋一定碰过图像数据标注的东西&#xff0c;当我们训练网络时需要训练集数据&#xff0c;但在网上又没有找到自己想要的数据集&#xff0c;这时候就考虑自己制作自己的数据集了&#xff0c;这时就需要对图像进行标注。图像标注是件很枯燥又很费人力物力的一件…