我需要通过套接字传输文件:
# 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相比,这似乎相当慢。有什么我做错了吗?
答案 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)已经完成了你正在做的事情