在Ruby中通过TCP套接字复制文件缓慢

时间:2011-08-25 09:43:01

标签: ruby sockets

我需要通过套接字传输文件:

# sender
require 'socket'
SIZE = 1024 * 1024 * 10

TCPSocket.open('127.0.0.1', 12345) do |socket| 
  File.open('c:/input.pdf', 'rb') do |file|
      while chunk = file.read(SIZE)
      socket.write(chunk)
    end
  end
end  


# receiver
require 'socket'
require 'benchmark'
SIZE = 1024 * 1024 * 10

server =  TCPServer.new("127.0.0.1", 12345)
puts "Server listening..."            
client = server.accept       

time = Benchmark.realtime do
  File.open('c:/output.pdf', 'w') do |file|
    while chunk = client.read(SIZE)
      file.write(chunk)
    end
  end
end

file_size = File.size('c:/output.pdf') / 1024 / 1024
puts "Time elapsed: #{time}. Transferred #{file_size} MB. Transfer per second: #{file_size / time} MB" and exit

使用Ruby 1.9在从/向localhost传输80MB PDF文件时,传输速率约为16MB / s(使用1.8时为~22MB / s)。我是套接字编程的新手,但与使用FileUtils.cp相比,这似乎相当慢。有什么我做错了吗?

2 个答案:

答案 0 :(得分:1)

好吧,即使使用localhost,您仍然必须通过部分的TCP堆栈,引入数据包碎片和重建的不可避免的延迟。它可能不会出现在每秒限制为100兆字节(~12.5 MB / s)或理论最大值为gigibit(~125 MB / s)的电线上。

对于将磁盘复制到磁盘的原始文件,不存在任何开销。你应该记住,即使SATA1给你1.5千兆比特/秒,如果你仍然在那个反向运行,我会感到惊讶。最重要的是,你的操作系统本身无疑会缓存很多东西,在通过TCP堆栈发送时是不可能的。

每秒16MB对我来说听起来不是太糟糕。

答案 1 :(得分:1)

我知道这个问题已经过时了,但为什么你不能在发送之前压缩,然后在接收端解压缩?

require 'zlib'

def compress(input)
  Zlib::Deflate.deflate(input)
end

def decompress(input)
  Zlib::Inflate.inflate(input)
end

(无耻插件)AFT(https://github.com/wlib/aft)已经完成了你正在做的事情