Problem with bind for Socket class


#1

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.


#2

On 14.10.2008 07:47, Vladimir F. 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


#3

On Tue, Oct 14, 2008 at 03:30:05PM +0900, Robert K. 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.


#4

On Oct 14, 8:34 am, Vladimir F. removed_email_address@domain.invalid
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.


#5

2008/10/14 Vladimir F. removed_email_address@domain.invalid:

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


#6

Hi,

On Tue, Oct 14, 2008 at 04:26:20PM +0900, Antonin A. 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.