python编写tftp服务器

  1. tftp服务起下载文件
  2.  from socket import *
     import struct 
     import os
     import sys
     
     
     def main():
         if len(sys.argv) != 3:
             print("请按照规则运行程序:python3 xxx.py ip filename")
             exit()
     
         #服务器ip
         tftp_ip = sys.argv[1]
     
         #文件名字
         file_name = sys.argv[2]
     
         #名字大小
         file_num = len(file_name)
     
         #下载请求
         cmd_buf = struct.pack("!H%dsb5sb"%file_num,1,file_name.encode("utf-8"),0,"octet".encode("utf-8"),0)
     
         #创建套接字
         socket_udp = socket(AF_INET,SOCK_DGRAM)
     
         #给服务器发送我需要的东西
         socket_udp.sendto(cmd_buf,(tftp_ip,69))
     
         #打开一个文件
         f = open(file_name,"bw")
     
         flag = True
     
         num = 0
     
         while True:
             result = socket_udp.recvfrom(1024)
             
             #数据     新ip端口
             tftp_data,tftp_ip_port = result
             
             #操作号
             cmd_tuple = struct.unpack("!H",tftp_data[:2])
     
             #块编号
             cmd_tuple2 = struct.unpack("!H",tftp_data[2:4])    
     
             #操作码
             tftp_opcode = cmd_tuple[0]
     
             #块编号
             tftp_serial_number = cmd_tuple2[0]
     
             #打印当前快编号
             print(tftp_serial_number)
     
     
             if tftp_opcode == 3: #是否为数据
     
                  #计算出这次应该接收到的文件的序号值,应该是上一次接收到的值的基础上+1
                 num = num + 1
     
                 # 如果一个下载的文件特别大,即接收到的数据包编号超过了2个字节的大小
                 # 那么会从0继续开始,所以这里需要判断,如果超过了65535 那么就改为0
                 if num == 65536: 
                     num = 0
                 
                 if num == tftp_serial_number: # 用块编号测试是否有重复数据
                     f.write(tftp_data[4:])
     
                 #测试Ack
                 cmd_buf2 = struct.pack("!HH",4,tftp_serial_number)
     
                 #把当前接收到的 快编号发送个服务器 随机端口和ip
                 socket_udp.sendto(cmd_buf2,tftp_ip_port)
                 
                 #测试数据长度
                 if len(tftp_data) < 516:
                     print("传输完毕.....")
                     break
     
             elif tftp_opcode == 5:
                 print("没有这个文件夹......")
                 flag = Falsh
     
         if flag == True:
             f.close() #关闭文件
     
         else:
             os.unlink(file_name)#没有这个文件 把创建的文件删除
     
         socket_udp.close() #关闭套接字
     
     
     if __name__ == "__main__":
         main()
    
  3. tftp服务器上传文件
  4.  from socket import *
     import struct
     import sys
     import os
     
     
     #上传的主要核心你要知道你是发送方
     #服务器是接收方  服务器反回确认信息,或者报错信息
     def main():
         if len(sys.argv) != 3:
             print("python3 xxx.py ip filename")
             exit()
     
     
         tftpd_ip = sys.argv[1]
         tftpd_file_name = sys.argv[2]
     
         #打包
         cmd_buf = struct.pack("!H%dsb5sb"%len(tftpd_file_name),2,tftpd_file_name.encode("utf-8"),0,"octet".encode("utf-8"),0)
     
         socket_udp = socket(AF_INET,SOCK_DGRAM)
     
         socket_udp.sendto(cmd_buf,(tftpd_ip,69))
     
         f = open(tftpd_file_name,"br")
     
         num = 1  #这里写1是因为  我上面发送了一次的
     
         flag = True
     
         while True:
             result = socket_udp.recvfrom(1024)
     
             #服务起反回的确认信息 和 ip port
             tftpd_data,tftpd_ip_port = result
     
             #操作号 服务的确认的操作好
             op_num = struct.unpack("!H",tftpd_data[:2])
     
             #块编号 服务起反回的快编号
             pack_num = struct.unpack("!H",tftpd_data[2:4])
     
             print(pack_num[0])
     
             if op_num[0] == 4:
                 
                 if num-1 == pack_num[0]:  # 这里写num-1  是因为 pack_num[0] 是反回的我上次发的快编号
                     send_data = f.read(512)
     
                     if len(send_data) < 512:
                         print("传输完成........")
                         break
                                                                     #num是快编号 因为我是发送方 我要自做个快比那好
                     cmd_bug = struct.pack("!HH%ds"%len(send_data),3,num,send_data) #send_data是读取的文件信息
                     socket_udp.sendto(cmd_bug,tftpd_ip_port) #发给服务器
     
                     num = num + 1 #我的快编号加1
     
             elif op_num[0] == 5:
                 print("没有这个文件......")
                 flag = Falsh
                 break
                 
         if flag == True:
             f.close()
         else:
             os.unlink(tftpd_file_name) #删除这个文件
     
     if __name__ == "__main__":
         main()
    

猜你喜欢

转载自blog.csdn.net/zsx1314lovezyf/article/details/89817090
今日推荐