Ruby TFTP服务器

我有以下代码,我为一个简单的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 

您可以使用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 

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

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

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

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

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

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

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

这里是我在2005年编写的示例代码,但id执行镜面reflection(它发送文件)它是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或在线搜索)

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