Non blocking socket keep blocking on read?

Hello everyone,

I have a problem with a socket that block (and my process alt) when the
server stop send me stuff. The server send me a couple of things ( file
name and so on ) and after that it send me a file ( a jpeg ). Everything
works ok but I have to force the read loop to break. How can I detect
that the server dont send me nothing anymore and break ? I was sure that
it will do it with connect_non_block ?

My problem is in the
while( buf = socket.readline )
it is where it hang when the server stop sending...

Here is my complete code...

    socket = Socket.new(AF_INET, SOCK_STREAM, 0)
    sockaddr = Socket.sockaddr_in(9401, '10.2.4.92')

    begin
      socket.connect_nonblock(sockaddr)
      rescue Errno::EINPROGRESS
       IO.select(nil, [socket])
       begin
         socket.connect_nonblock(sockaddr)
       rescue Errno::EISCONN
        end
     end

     puts "sending..."

    begin

       socket.write("207\n")
       socket.write("146316\n")
       socket.write( "89c38b1b197162cae874e5274963633f" + "\n")

       puts "receiving..."

       i=0
       while data = socket.readline
        puts "data : " + data

        if i == 0
          puts "Return code : " + data
        end

        if i == 1
          puts "Bytes to receive : " + data
          nombre_bytes = data
        end

        if i == 2
          puts "File name : " + data
       end

        if i == 2
          break;
       end

        i = i+1

       end

     i = 0;
     while( buf = socket.readline )
        puts "here"
        puts buf
        puts " i = " + i.to_s;

        if( @imageData == nil )
          @imageData = buf
      else
            @imageData += buf
        end

        i = i + 1

        #I Dont want to do this
        #with this all works because I kow the the server ships
        #me the test file in 26 chunk
        #I wanna detect that readline read nothing instead !
        if( i == 27 )
          break;
        end

     end

      socket.close

      rescue Exception => exc
         puts "erreur #{exc.message}"
         puts exc.inspect
        socket.close

    end

  end

Thx for your comments !

Seurdge

···

--
Posted via http://www.ruby-forum.com/.

Hi Sergey

The server sends you the size of the image, so you can use that to
check when the download completed. Also check the way you are reading
the image, you are using IO::readline which is generally used to read
lines of text. Take a look at IO::read to download the image.

···

--
Luis Parravicini
http://ktulu.com.ar/blog/

Ths Luis !

But how do I know the weight of the received bytes ? I have think of
what you propose but can't find the way to "measure" the received stuff
!!!

I have to use readline or gets to receive because the server (a java
server) only offer me buffered stream and recv and read dont work in
this case...

Serge

Luis Parravicini wrote:

···

Hi Sergey

The server sends you the size of the image, so you can use that to
check when the download completed. Also check the way you are reading
the image, you are using IO::readline which is generally used to read
lines of text. Take a look at IO::read to download the image.

--
Posted via http://www.ruby-forum.com/\.

It doesn't matter if the server is using a buffered stream, you'll
get the bytes on the client anyway. Maybe something like this helps
(haven't tried it):

data = nil
left = nombre_bytes
while left > 0
  # 8192 is an arbitrary buffer size
  buf = socket.read( left > 8192 ? 8192 : left )
  # eof reached
  break unless buf

  left -= buf.size
  data += buf
end

@imageData = data

Why are you using a while to read return code, filename and size?
Three socket.readline should be enough.

Bye

···

On Wed, Oct 1, 2008 at 10:53 AM, Serge Savoie <seurdge.sawa@gmail.com> wrote:

But how do I know the weight of the received bytes ? I have think of
what you propose but can't find the way to "measure" the received stuff
!!!

I have to use readline or gets to receive because the server (a java
server) only offer me buffered stream and recv and read dont work in
this case...

--
Luis Parravicini
http://ktulu.com.ar/blog/

Thx a lot Luis :wink:

The Java server now send me a signal for "end of transmission" so I do
not have the check the weight of the transfer...

"Why are you using a while to read return code, filename and size? Three
socket.readline should be enough."

yeah sure, but its just cheesy test code lol

Thx again for your rapid reply and have a nice day !

Luis Parravicini wrote:

···

On Wed, Oct 1, 2008 at 10:53 AM, Serge Savoie <seurdge.sawa@gmail.com> > wrote:

But how do I know the weight of the received bytes ? I have think of
what you propose but can't find the way to "measure" the received stuff
!!!

I have to use readline or gets to receive because the server (a java
server) only offer me buffered stream and recv and read dont work in
this case...

  It doesn't matter if the server is using a buffered stream, you'll
get the bytes on the client anyway. Maybe something like this helps
(haven't tried it):

data = nil
left = nombre_bytes
while left > 0
  # 8192 is an arbitrary buffer size
  buf = socket.read( left > 8192 ? 8192 : left )
  # eof reached
  break unless buf

  left -= buf.size
  data += buf
end

@imageData = data

Why are you using a while to read return code, filename and size?
Three socket.readline should be enough.

Bye

--
Posted via http://www.ruby-forum.com/\.