Ruby TFTP Server

I have the following code that I compiled for a simple Ruby TFTP server. It works great in that it listens on port 69, and my TFTP client connects to it, and I can write packets in test.txt, but instead of just writing packets, I want to be able to TFTP file from my client to a directory / temp.

Thanks in advance for your help!

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
+5
source share
2 answers

Instead of writing in /temp/test.txt you can use ruby TEMPFILE class

So in your example:

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

This will create a guaranteed unique temporary file in your / tmp directory with a name based on "tftpserver".

EDIT: , /temp (not/tmp), , Tempfile.new('tftpserver', '/temp'), .

2: , , , https://github.com/spiceworks/net-tftp

+7

, 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

arpa/tftp.h( unix )

- ( ) ! H struct pack Ruby - python String

+5

All Articles