[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Sending Binary Data?

Yacin Nadji

2/28/2006 8:52:00 AM

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

file = File.open("new.jpg","w")
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+")
server = TCPServer.new('localhost', port)
while session = server.accept
file.write(session.gets)
server.close
file.close
end

client.rb

require 'socket'

server = TCPSocket.new('localhost',9191)
file = String.new
IO.foreach("lighter.jpg") do |line|
file += line.chomp
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.

Thanks!

Yacin Nadji


2 Answers

Robert Klemme

2/28/2006 9:07:00 AM

0

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

Logan Capaldo

3/1/2006 2:52:00 AM

0


On Feb 28, 2006, at 3:52 AM, Yacin Nadji wrote:

> server = TCPSocket.new('localhost',9191)
> file = String.new
> IO.foreach("lighter.jpg") do |line|
> file += line.chomp
> end

try deleting the .chomp. Jpg's aren't really line oriented anyway.
Also if you are on windows not opening the file in binary mode will
wreak also sorts of havoc. As an alternative try this:

a = File.open("lighter.jpg", "rb") { |f| f.read }