Ruby TFTP服务器

rah*_*uby 5 ruby

我有以下代码,我为一个简单的Ruby TFTP服务器放在一起.它工作正常,它侦听端口69,我的TFTP客户端连接到它,我能够将数据包写入test.txt,但我不想只写数据包,我希望能够从我的客户端TFTP文件到/ temp目录.

在此先感谢您的帮助!

require 'socket.so'

class TFTPServer
  def initialize(port)
    @port = port
  end

  def start
    @socket = UDPSocket.new
    @socket.bind('', @port)
    while true
      packet = @socket.recvfrom(1024)
      puts packet

      File.open('/temp/test.txt', 'w') do |p|
            p.puts packet   
        end 
    end
  end
end

server = TFTPServer.new(69)
server.start
Run Code Online (Sandbox Code Playgroud)

die*_*mes 7

您可以使用ruby的Tempfile类,而不是写入/temp/test.txt

所以在你的例子中:

require 'socket.so'
require 'tempfile'

class TFTPServer
  def initialize(port)
   @port = port
  end

  def start
    @socket = UDPSocket.new
    @socket.bind('', @port)
    while true
      packet = @socket.recvfrom(1024)
      puts packet

      Tempfile.new('tftpserver') do |p|
        p.puts process_packet( packet )
      end 
    end
  end
end

server = TFTPServer.new(69)
server.start
Run Code Online (Sandbox Code Playgroud)

这将在/ tmp目录中创建一个保证唯一的临时文件,其名称基于'tftpserver'.

编辑:我注意到你想写/ temp(而不是/ tmp)这样做你可以做到Tempfile.new('tftpserver', '/temp')指定一个特定的临时目录.

编辑2:对于任何有兴趣的人,都有一个可以执行此操作的库https://github.com/spiceworks/net-tftp


she*_*pya 5

你不会这么容易得到它,tftp协议相对容易,但put/get不是无状态的,或者至少如果文件不适合单个数据包,就像512,但有些扩展允许更大包

线路上的文件被拆分,你将得到一个数据包序列,每个数据包都有一个序列号,所以另一端可以发送特定数据包的错误

你应该看一下维基百科页面:

http://en.wikipedia.org/wiki/Trivial_File_Transfer_Protocol

这里是我在2005年编写的示例代码,但id执行镜面反射(它发送文件)它是python但与ruby相似:D

def send_file(self, addr, filesend, filesize, blocksize):
    print '[send_file] Sending %s (size: %d - blksize: %d) to %s:%d' % (filesend, filesize, blocksize, addr[0], addr[1])
    fd = open(filesend, 'rb')

    for c in range(1, (filesize / blocksize) + 2):
        hdr = pack('!H', DATA) + pack('!H', c)
        indata = fd.read(blocksize)
        if debug > 5: print '[send_file] [%s] Sending block %d size %d' % (filesend, c, len(indata))
        self.s.sendto(hdr + indata, addr)
        data, addr = self.s.recvfrom(1024)
        res = unpack('!H', data[:2])[0]
        data = data[2:]
        if res != ACK:
            print '[send_file] Transfer aborted: %s' % errors[res]
            break
        if debug > 5:
            print '[send_file] [%s] Received ack for block %d' % (filesend, unpack('>H', data[:2])[0] + 1)
    fd.close()

    ## End Transfer
    pkt = pack('!H', DATA) + pack('>H', c) + NULL
    self.s.sendto(pkt, addr)
    if debug: print '[send_file] File send Done (%d)' % c
Run Code Online (Sandbox Code Playgroud)

你可以在arpa/tftp.h中找到常量(你需要一个unix或在线搜索)

序列号是一个大端(网络顺序)简短!struct pack ruby​​的H格式有类似String类中的python结构