Python TFTP上传与下载

一、上传的步骤
1.在服务器上创建一个空文件
2.打开本地文件读取内容
3.将内容分批传给服务器
4.传输完成,关闭文件操作
二、下载的步骤
1.在本地上创建一个空文件
2.向服务器发送读取请求
3.服务器将内容分批传给本地
4.传输完成,关闭文件操作
三、TFTP(简单文件传输协议)


tftp.png

1.由本地向服务器发起读写请求


读写请求.png

2.收发数据包
数据包.png

3.ACK确认
ACK.png

4.ERROR错误信息
ERROR.png

四、实现代码
from socket import *
import struct

server_ip = ""

#创建udp
def create_socket():
    udps = socket(AF_INET, SOCK_DGRAM)
    return udps

#文件读写
def file_operate(udps,type):
    file_name = input("请输入需要操作的文件路径")
    if type == 1:
        operate_file = open(file_name, "ab")
    else:
        operate_file = open(file_name, "rb")
    tftp(udps,type,file_name,operate_file)
    operate_file.close()

#实现tftp协议
def tftp(udps,type,file_name,operate_file):
    pak = struct.pack("!H6sb5sb", type, file_name.encode("utf-8"), 0, b"octet", 0)
    addr = (server_ip, 69)
    udps.sendto(pak, addr)#向服务器发送读写请求
    while True:
        content = udps.recvfrom(516)#接收服务器返回的确认信息
        if type == 1:#tftp下载
            ret = struct.unpack("!HH", content[0][:4])#二元元组,[0]服务器操作码信息加512字节数据(3:数据包,4:ACK,5:ERROR),[1]块编码
            operate_file.write(content[0][4:])#若操作码不为5,则写入数据(此处判断省略)
            ack_pak = struct.pack("!HH", 4, ret[1])
            udps.sendto(ack_pak, content[1])#向服务器发送ACK确认信息
            if len(content[0]) < 516:#当服务器返回的确认信息小于516个字节时,即为传输完毕
                break
        else:#tftp上传
            ret = struct.unpack("!HH", content[0])#同下载的ret变量
            upc = operate_file.read(512)#若操作码不为5,则读取最大512字节数据用于发送
            data_pak = struct.pack("!HH512s", 3, ret[1] + 1, upc)#打包上传信息,块编码需自增1
            udps.sendto(data_pak, content[1])#向服务器发送文件数据
            if len(upc) < 512:#当文件读取内容不足512字节时,即为传输完毕
                break


if __name__ == '__main__':
    global server_ip
    server_ip = input("请输入服务器ip:")
    tp_type = int(input("请选择传输类型(下载:1,上传:2):"))
    udps = create_socket()
    file_operate(udps,tp_type)

你可能感兴趣的:(Python TFTP上传与下载)