From: Robert Klemme Date: 2006-02-28T18:08:38+09:00 Subject: Re: Sending Binary Data? Yacin Nadji wrote: > Hello Ruby Gurus! > > My friend and I are writing a chat/IM client in Ruby. It's nothing > special, but it's helping us learn the language, especially the lower > level networking parts really well and I'm thoroughly enjoying the > project so far. I thought implementing file transfers would be pretty > nifty, but I'm running into some problems. I did a simple copy by > reading the file (a picture) and adding the lines to a string, and > writing that string out to a new file: > > a = String.new > > IO.foreach("lighter.jpg") do |line| > a += line > end This approach is quite inefficient in two ways: - you use + for string concatenation which constantly creates new objects and throws old ones away. Better use << - You need to keep the whole file in mem while with a streaming approach (reading and writing a chunk at a time only) you can deal with arbitrary sized files without worrying about memory. > file = File.open("new.jpg","w") You should use mode "wb" - even if on Linux. > file.write(a) > file.close > > And it worked swimmingly, however, when I tried to do this over a > TCPClient/Server: > > server.rb > > require 'socket' > port = 9191 > file = File.open("omgnew.jpg","w+") "wb" again... > server = TCPServer.new('localhost', port) > while session = server.accept > file.write(session.gets) Better use #read and #write instead of gets! > server.close > file.close > end > > client.rb > > require 'socket' > > server = TCPSocket.new('localhost',9191) You want TCPServer here. > file = String.new > IO.foreach("lighter.jpg") do |line| > file += line.chomp > end # untested srv = TCPServer.new('localhost',9191) while ( sess = srv.accept ) Thread.new(sess) do |session| File.open("lighter.jpg", "rb") |io| session.write(io.read(1024)) end end end > server.send(file,0) > > > It works for a bit, then I get this error: > > server.rb:7:in `accept': closed stream (IOError) > from server.rb:7 > > The file sizes are nearly identical, I'm off by 479 bytes: > > ynadji@onizuka:file_transfer$ du -b * > 122753 lighter.jpg > 122274 omgnew.jpg > > Any ideas? I could be doing this entirely wrong, searching didn't > yield any helpful results, so I figured I'd turn here. I was reading > around with Array#pack and String#unpack which seems to be heading in > the right direction, but I'm completely lost :P. Hope I could give some valuable hints. Kind regards robert