• Python的网络编程[2] -> TFTP 协议[1] -> TFTP 的 Python 实现


    TFTP实现 / TFTP Implement


    目录

    1. TFTP 的服务器建立过程
    2. TFTP 的客户端建立过程

    1 TFTP 的服务器建立过程

    服务器建立步骤主要有:

    (1)      设定服务器IP和端口号(常用69),建立socket并bind地址;

    (2)      设定服务器工作目录;

    (3)      建立主循环进行监听,根据收到的信息选择读/写模式;

    (4)      (建立新的线程及socket)执行上传下载操作;

    (5)      下载操作: block number设置为1—打开需要下载的文件—进入循环—读取512byte数据—发送读取的数据—等待ACK报文(超时重发)—确认opcode—确认数据长度是否结束(结束则进行结束处理,并关闭文件)11—block number +1;

    (6)      上传操作: block number 设置为0—发送ACK报文—block number +1—打开新的文件存储上传数据—进入循环—等待接收DATA报文—确认opcode—写入数据—发送ACK报文—确认数据长度是否结束(结束则进行结束处理,并关闭文件)—block number +1。

    Note: 关于THTP_Helper 的 TFTP 的加解码过程请参考 TFTP 加解码部分

     1 import importlib
     2 from TFTP_Helper import *
     3 import socket
     4 from threading import Thread
     5 
     6 
     7 class TFTPServer():
     8     def __init__(self):
     9         ip = '127.0.0.1'
    10         port = 69
    11         address = (ip, port)
    12         self.home_path = 'TFTPServerFile'
    13         self.server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    14         self.server.bind(address)
    15 
    16     def readRequest(self, file_name, addr):
    17         print('<<< RRQ', '
    === Read request, starting file %s downing to client' % file_name, end='')
    18         sock_down = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    19         block_num = 1
    20         try:
    21             f = open(self.home_path + '\' + file_name, 'rb')
    22         except:
    23             # file no found, exit thread
    24             print('=== File %s no found' % file_name)
    25             exit()
    26         while True:
    27             down_data = f.read(512)     # data is byte format
    28             sock_down.sendto(TFTPData.encode(block_num, down_data), addr)
    29             print('>>> DATA', block_num)
    30             ack_msg, ack_addr = sock_down.recvfrom(1024)
    31             print('<<< ACK ', block_num)
    32             opcode, ack_block_num = TFTPAck.decode(ack_msg)
    33             assert opcode == 4 and ack_block_num == block_num, 'Invalid ack message.'
    34             if len(down_data) < 512:
    35                 block_num = 1
    36                 print('=== Transmission of %s completed' % file_name)
    37                 f.close()
    38                 exit()
    39             block_num += 1
    40         print('=== Close file')
    41         f.close()
    42 
    43     def writeRequest(self, file_name, addr):
    44         print('<<< WRQ', '
    === Write request, starting file %s uploading to server' % file_name)
    45         sock_upload = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    46         block_num = 0
    47         sock_upload.sendto(TFTPAck.encode(block_num), addr)
    48         print('>>> ACK')
    49         try:
    50             f = open('TFTPServerFIle\Copy-'+file_name, 'wb')
    51         except:
    52             print('=== File "%s" no found' % file_name)
    53             exit()
    54         block_num += 1
    55         while True:
    56             recv_data, addr = sock_upload.recvfrom(1024)
    57             opcode, block_num_recv, data = TFTPData.decode(recv_data)
    58             print('<<< DATA')
    59             if opcode != 3 or block_num != block_num_recv:
    60                 print('=== Error Opcode or Block Number')
    61                 # TODO: add error msg send and handle here
    62                 exit()
    63             f.write(data)
    64             sock_upload.sendto(TFTPAck.encode(block_num), addr)
    65             print('>>> ACK')
    66             if len(data) < 512:
    67                 # TODO: add transmission completed handle here
    68                 block_num = 1
    69                 print('=== File "%s" transmission completed' % file_name)
    70                 f.close()
    71                 exit()
    72             block_num += 1
    73 
    74     def server_run(self):
    75         while True:
    76             print('=== Waiting client')
    77             msg, addr = self.server.recvfrom(1024)
    78             print('<<< Receive a connection from client %s, msg is %s' % (addr, msg))
    79             opcode, file_name = TFTPReadWriteRequest.decode(msg)
    80             cmdSelect = {1: Thread(target=self.readRequest, args=(file_name, addr)),
    81                          2: Thread(target=self.writeRequest, args=(file_name, addr))}
    82             try:
    83                 cmdSelect[opcode].start()
    84             except:
    85                 print('<<< Receive error opcode%s' % opcode)
    86                 raise ErrorOpcode
    87 
    88 server = TFTPServer()
    89 server.server_run()

    2 TFTP 的客户端建立过程

    客户端建立步骤主要有:

    (1)      获取服务器ip和端口;

    (2)      下载操作: 建立下载socket—发送RRQ下载请求—设置block number为1—新建文件存储下载数据—进入循环—等待接收DATA报文—确认opcode—写入数据—发送ACK报文—确认数据长度是否结束(结束则进行结束处理,并关闭文件)—block number +1;

    (3)      上传操作: 建立上传socket—发送WRQ上传请求—等待ACK报文—设置block number为0—确认opcode—打开需要上传的文件—进入循环—读取数据—发送DATA报文—接收ACK报文—确认opcode—确认数据长度是否结束(结束则进行结束处理,并关闭文件)—block number +1;

     1 from TFTP_Helper import *
     2 import socket
     3 
     4 
     5 class TFTPClient():
     6     def __init__(self):
     7         server_ip = '127.0.0.1'
     8         port = 69
     9         self.address = (server_ip, port)
    10 
    11     def readRequest(self, file_name):
    12         sock_down = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    13         send_data = TFTPReadWriteRequest.encode('r', file_name)
    14         sock_down.sendto(send_data, self.address)
    15         block_num = 1
    16         try:
    17             f = open('TFTPClientFIlecopy-'+file_name, 'wb')
    18         except:
    19             print('--- File "%s" no found' % file_name)
    20             exit()
    21         while True:
    22             recv_data, recv_addr = sock_down.recvfrom(1024)
    23             print('<<< DATA', block_num)
    24             opcode, block_num_recv, data = TFTPData.decode(recv_data)
    25             if opcode != 3 or block_num != block_num_recv:
    26                 print('--- Opcode or Block Number Error')
    27                 # TODO: add error msg send and handle here
    28                 break
    29             f.write(data)
    30             sock_down.sendto(TFTPAck.encode(block_num), recv_addr)
    31             print('>>> ACK ', block_num)
    32             if len(data) < 512:
    33                 # TODO: add transmission completed handle here
    34                 block_num = 1
    35                 print('--- File "%s" transmission completed' % file_name)
    36                 f.close()
    37                 break
    38             block_num += 1
    39 
    40     def writeRequest(self, file_name):
    41         sock_upload = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    42         send_data = TFTPReadWriteRequest.encode('w', file_name)
    43         sock_upload.sendto(send_data, self.address)
    44         print('>>> WRQ')
    45         recv_data, addr = sock_upload.recvfrom(1024)
    46         print('<<< ACK')
    47         opcode, ack_block = TFTPAck.decode(recv_data)
    48         block_num = 0
    49         if opcode != 4 or ack_block != block_num:
    50             print('--- Error Opcode or Block Number')
    51             # TODO: add error msg send and handle here
    52             exit()
    53         try:
    54             f = open('TFTPClientFIle\'+file_name, 'rb')
    55         except:
    56             print('--- File "%s" no found' % file_name)
    57             exit()
    58         block_num += 1
    59         while True:
    60             upload_data = f.read(512)
    61             sock_upload.sendto(TFTPData.encode(block_num, upload_data), addr)
    62             print('>>> DATA')
    63             ack_msg, addr = sock_upload.recvfrom(1024)
    64             print('<<< ACK')
    65             opcode, ack_block_num = TFTPAck.decode(ack_msg)
    66             assert opcode == 4 and ack_block_num == block_num, 'Invalid ack message.'
    67             if len(upload_data) < 512:
    68                 # TODO: add transmission completed handle here
    69                 block_num = 1
    70                 print('--- File "%s" transmission completed' % file_name)
    71                 f.close()
    72                 break
    73             block_num += 1
    74 
    75 
    76 tftp = TFTPClient()
    77 for file in ['downFile.py', 'downFile.docx', 'downFile.txt', 'downFile.zip']:
    78     tftp.readRequest(file)
    79 for file in ['uploadFile.py', 'uploadFile.docx', 'uploadFile.txt', 'uploadFile.zip']:
    80     tftp.writeRequest(file)


    相关阅读


    1. TFTP 的基本理论

    2. struct 模块

  • 相关阅读:
    多样三角形
    字符串转化去重
    捕获异常里面的特殊异常
    sqlalchemy.exc.CompileError: (in table 'language_label', column 'name'): VARCHAR requires a length o
    机器学习总结
    找出两个列表中相同元素与不同元素
    正则去重
    mysql5.7 安装重置密码
    chrome快捷键
    golang select
  • 原文地址:https://www.cnblogs.com/stacklike/p/8149533.html
Copyright © 2020-2023  润新知