zoukankan      html  css  js  c++  java
  • Python设计TFTP客户端

    #coding=utf-8
    
    from socket import *
    from threading import Thread
    import struct
    
    def recvData(fileName,udpSocket,lastBlockNum):
        lastBlockNum = lastBlockNum
        cycleIndex = 0 #当文件较大,块编号大于65535时,循环索引加1,重置块编号为1
        while True:
            dataInfo, dstInfo = udpSocket.recvfrom(1024)
            opCode,blockNum = struct.unpack("!HH",dataInfo[:4])
            if opCode == 3:
                if blockNum == 1 and cycleIndex==0:
                    f = open(fileName,'wb')
                data_fmt = '!%ds'%(len(dataInfo)-4)
                data_content = struct.unpack(data_fmt,dataInfo[4:])
    
                if lastBlockNum+1 == blockNum:
                    f.write(data_content[0])
    
                ack_data = struct.pack("!HH",4,blockNum)
                udpSocket.sendto(ack_data,dstInfo)
    
                if blockNum==65535:
                    cycleIndex += 1
                    lastBlockNum = blockNumelif blockNum>65535:
                    lastBlockNum=0
                else:
                    lastBlockNum = blockNum
    
                if len(dataInfo)<516:
                    print("下载完毕!")
                    f.close()
                    break
            elif opCode == 5:
                errorNum = blockNum
                err_fmt = "!%ds"%(len(dataInfo)-5)
                errorMsg = struct.unpack(err_fmt,dataInfo[4:-1])
                print("出错信息%s %s"%(errorMsg,errorNum))
                break
    
    
    def sendData(fileName,udpSocket):
        ipInfo = ("10.0.0.4", 69)
        dataInfo = struct.pack("!H%dsB5sB"%len(fileName), 1, fileName.encode("gb2312"), 0, 'octet'.encode("gb2312"), 0)
        udpSocket.sendto(dataInfo, ipInfo)
    
    def main():
        fileName = "CentOS-7-x86_64-Minimal-1611.iso"
        udpSocket = socket(AF_INET, SOCK_DGRAM)
        bind = ("", 38438)
        udpSocket.bind(bind)
        lastBlockNum = 0
    
        t1 = Thread(target=sendData,args=(fileName,udpSocket,))
        t1.start()
    
        t2 = Thread(target=recvData,args=(fileName,udpSocket,lastBlockNum))
        t2.start()
    
    if __name__ == "__main__":
        main()
    转载请注明出处:http://www.cnblogs.com/sexyboy/
  • 相关阅读:
    C++ template —— 模板基础(一)
    《C++标准程序库》笔记之四
    《C++标准程序库》笔记之三
    《C++标准程序库》笔记之二
    C++标准程序库笔记之一
    JAVA中JPA的主键自增长注解设置
    SVN中服务器地址变更
    JAVA中正则表达式常用的四个方法
    反编译class文件并重新编译的方法
    JAVA中文件与Byte数组相互转换的方法
  • 原文地址:https://www.cnblogs.com/sexyboy/p/8509578.html
Copyright © 2011-2022 走看看