zoukankan      html  css  js  c++  java
  • TFTP 服务器

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

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

    特点:

    • 简单
    • 占用资源小
    • 适合传递小文件
    • 适合在局域网进行传递
    • 端口号为69
    • 基于UDP实现

     

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

    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()
  • 相关阅读:
    Spring Boot 入门
    门罗币(MONERO)钱包生成教程
    数据库 一对多,多对多 表设计
    使用nginx+lua脚本读写redis缓存
    在Spring MVC中使用注解的方式校验RequestParams
    MySQL命名、设计及使用规范《MySQL命名、设计及使用规范》
    Mycat分表分库
    Go在Ubuntu 14.04 64位上的安装过程
    Android获取设备屏幕宽高像素值的两个方法
    php_curl.dll libssh2.dll 始终无法加载的原因 及解决办法
  • 原文地址:https://www.cnblogs.com/ghming/p/8810235.html
Copyright © 2011-2022 走看看