• 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()
  • 相关阅读:
    ACM HDU 3910 Liang Guo Sha(数学题,读懂题目)
    防止 7Zip 生成的 ZIP 文件在 Mac OS X 下出现乱码
    NYOJ 506
    Scanner
    String 与StringBuilder
    基于JAVA的聊天室开发
    PS加粗字体
    MySQL相关命令
    Matlab中数据处理和多项式插值与曲线拟合
    dos下进入某一文件
  • 原文地址:https://www.cnblogs.com/venicid/p/7994995.html
Copyright © 2020-2023  润新知