Sending Binary Data?

Discussion in 'Ruby' started by Yacin Nadji, Feb 28, 2006.

  1. Yacin Nadji

    Yacin Nadji Guest

    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
    Yacin Nadji, Feb 28, 2006
    #1
    1. Advertising

  2. 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
    Robert Klemme, Feb 28, 2006
    #2
    1. Advertising

  3. --Apple-Mail-11--359922324
    Content-Transfer-Encoding: 7bit
    Content-Type: text/plain;
    charset=US-ASCII;
    delsp=yes;
    format=flowed


    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 }


    --Apple-Mail-11--359922324--
    Logan Capaldo, Mar 1, 2006
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?U2Nod2FydHk=?=

    Sending binary data to client printer via web page.

    =?Utf-8?B?U2Nod2FydHk=?=, Feb 8, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    6,337
    Yuan Ren[MSFT]
    Feb 13, 2006
  2. Replies:
    5
    Views:
    1,477
    =?ISO-8859-15?Q?Juli=E1n?= Albo
    May 14, 2005
  3. Walter Huf

    Sending binary data over CGI

    Walter Huf, Mar 4, 2004, in forum: Python
    Replies:
    3
    Views:
    1,203
    Walter Huf
    Mar 4, 2004
  4. Replies:
    9
    Views:
    1,061
    Simon Forman
    Jul 4, 2006
  5. David Hirschfield

    Sending binary pickled data through TCP

    David Hirschfield, Oct 13, 2006, in forum: Python
    Replies:
    4
    Views:
    297
    Irmen de Jong
    Oct 13, 2006
Loading...

Share This Page