# Non blocking socket keep blocking on read?

**URL:** <https://www.ruby-forum.com/t/non-blocking-socket-keep-blocking-on-read/149954>\
**Category:** Ruby\
**Created:** [October 1, 2008, 3:34pm UTC](https://www.ruby-forum.com/t/non-blocking-socket-keep-blocking-on-read/149954 "2008-10-01T15:34:55Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![seurdge](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/edb3f5/32.png) [@seurdge](https://www.ruby-forum.com/u/seurdge)\
**Post date:** [October 1, 2008, 3:34pm UTC](https://www.ruby-forum.com/t/non-blocking-socket-keep-blocking-on-read/149954/1 "2008-10-01T15:34:55Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![seurdge](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/edb3f5/32.png) [@seurdge](https://www.ruby-forum.com/u/seurdge)\
**Post date:** [October 1, 2008, 3:51pm UTC](https://www.ruby-forum.com/t/non-blocking-socket-keep-blocking-on-read/149954/2 "2008-10-01T15:51:07Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![seurdge](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/edb3f5/32.png) [@seurdge](https://www.ruby-forum.com/u/seurdge)\
**Post date:** [October 1, 2008, 3:55pm UTC](https://www.ruby-forum.com/t/non-blocking-socket-keep-blocking-on-read/149954/3 "2008-10-01T15:55:02Z")

</div>

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 P. 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.

---

<div class="post-metadata">

**Author:** ![seurdge](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/edb3f5/32.png) [@seurdge](https://www.ruby-forum.com/u/seurdge)\
**Post date:** [October 1, 2008, 5:17pm UTC](https://www.ruby-forum.com/t/non-blocking-socket-keep-blocking-on-read/149954/4 "2008-10-01T17:17:14Z")

</div>

Thx a lot Luis 😉

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 P. wrote:

> On Wed, Oct 1, 2008 at 10:53 AM, Serge S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> 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

---

<div class="post-metadata">

**Author:** ![seurdge](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/edb3f5/32.png) [@seurdge](https://www.ruby-forum.com/u/seurdge)\
**Post date:** [October 1, 2008, 5:09pm UTC](https://www.ruby-forum.com/t/non-blocking-socket-keep-blocking-on-read/149954/5 "2008-10-01T17:09:58Z")

</div>

On Wed, Oct 1, 2008 at 10:53 AM, Serge S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
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
