Forum: Ruby Problem with bind for Socket class

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
59c436d6801db18313ff1b27369bc8dd?d=identicon&s=25 Vladimir Fekete (Guest)
on 2008-10-14 07:47
(Received via mailing list)
Hi *,
   I have following problem, I'm playing with socket class and I wanted
to
test the example from

http://www.ruby-doc.org/stdlib/libdoc/socket/rdoc/index.html

e.g.:
#-------------------------------------------------------------------
require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
socket.bind( sockaddr )
socket.listen( 5 )
client_fd, client_sockaddr = socket.sysaccept
client_socket = Socket.for_fd( client_fd )
puts "The client said, '#{client_socket.readline.chomp}'"
client_socket.puts "Hello from script one!"
socket.close
#-------------------------------------------------------------------

I changed the code slightly to :

#-------------------------------------------------------------------
require 'socket'
include Socket::Constants

$shutdown = false

socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 2201, 'localhost' )
socket.bind( sockaddr )
socket.listen( 5 )

loop do
        if (IO.select([socket],nil,nil,0.1)!=nil) then
                client, client_sockaddr = socket.accept
                puts "NEW CLIENT : " + client_sockaddr.inspect.to_s
                Thread.start(client) do |a|
                        str = a.recv(100);
                        $shutdown = true if str=="shutdown"
                        a.close
                        puts str.to_s + "  " + $shutdown.to_s
                end
        end

        break if $shutdown==true
end

puts "SHutting down..."
socket.close
#--------------------------------------------------------------------

when I tested it it worked. But when I tried to run it again I've got
error
message:

./t1.rb:10:in `bind': Address already in use - bind(2)
(Errno::EADDRINUSE)
        from ./t1.rb:10

I tried to find "related" bug/problem in google but withouth success.
Could anybody
help me how to "unbind" socket ? Or explain me where I making mistake. I
have
some experiences only with WinSock API and I don't remember any unbind
function.
Many thanks!

Cheers,

 V.

P.S. I'm running it on Debian Linux, Ruby version 1.8.
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2008-10-14 08:32
(Received via mailing list)
On 14.10.2008 07:47, Vladimir Fekete wrote:

> when I tested it it worked. But when I tried to run it again I've got error
> message:
>
> /t1.rb:10:in `bind': Address already in use - bind(2) (Errno::EADDRINUSE)
>         from ./t1.rb:10
>
> I tried to find "related" bug/problem in google but withouth success. Could anybody
> help me how to "unbind" socket ? Or explain me where I making mistake. I have
> some experiences only with WinSock API and I don't remember any unbind function.

> P.S. I'm running it on Debian Linux, Ruby version 1.8.

I remember that on some OS (or particular versions) socket cleanout is
delayed.  Did you try to check with "netstat -a -n | fgrep 2201" or
similar to see what state the port is in?

Cheers

  robert
59c436d6801db18313ff1b27369bc8dd?d=identicon&s=25 Vladimir Fekete (Guest)
on 2008-10-14 08:35
(Received via mailing list)
On Tue, Oct 14, 2008 at 03:30:05PM +0900, Robert Klemme wrote:
> >help me how to "unbind" socket ? Or explain me where I making mistake. I
> >have
> >some experiences only with WinSock API and I don't remember any unbind
> >function.
>
> >P.S. I'm running it on Debian Linux, Ruby version 1.8.
>
> I remember that on some OS (or particular versions) socket cleanout is
> delayed.  Did you try to check with "netstat -a -n | fgrep 2201" or
> similar to see what state the port is in?

Yes you are right, after circa 5 minutes it works again. So you say it
is
problem (issue) of OS and not ruby, yes ?

 Cheers,

  V.
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2008-10-14 09:12
(Received via mailing list)
2008/10/14 Vladimir Fekete <fekete@melkor.dnp.fmph.uniba.sk>:
>> >
>> delayed.  Did you try to check with "netstat -a -n | fgrep 2201" or
>> similar to see what state the port is in?
>
> Yes you are right, after circa 5 minutes it works again. So you say it is
> problem (issue) of OS and not ruby, yes ?

Maybe.  You would have to check the web for the particular version of
OS you use and system settings to be sure.

In any case I would change the code in a way to ensure the socket is
properly closed when the program terminates (either via begin - ensure
- end or via at_exit).

Kind regards

robert
4fc30068499179fc708fe5dec2c95919?d=identicon&s=25 Antonin Amand (Guest)
on 2008-10-14 09:26
(Received via mailing list)
On Oct 14, 8:34 am, Vladimir Fekete <fek...@melkor.dnp.fmph.uniba.sk>
wrote:
> > >Could anybody
>
> Yes you are right, after circa 5 minutes it works again. So you say it is
> problem (issue) of OS and not ruby, yes ?

If you want to reuse the port you must set this flag on the socket
before you bind it.
When you use this kind of option you must ensure that you can't run
multiple instances of the program.
Use a lock file or something.

  socket.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)

Cheers.
59c436d6801db18313ff1b27369bc8dd?d=identicon&s=25 Vladimir Fekete (Guest)
on 2008-10-14 10:19
(Received via mailing list)
Hi,


On Tue, Oct 14, 2008 at 04:26:20PM +0900, Antonin Amand wrote:
> > > >/t1.rb:10:in `bind': Address already in use - bind(2) (Errno::EADDRINUSE)
> >
> multiple instances of the program.
> Use a lock file or something.
>
>   socket.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true)

nope, no help. I still have to wait.

 V.
This topic is locked and can not be replied to.