Ruby Bug? Windows and UDPSocket and Errno:ENOTCONN

If I have a pair of Win2k Ruby processes bouncing UDP packets back and
forth…

After awhile one of them dies with Errno::ENOTCONN

The code works under Linux but not under Win2k, neither on ruby-1.8.6
nor 1.8.7.

Any guesses? Suggestions? Workarounds?

John C. Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : [email protected]
New Zealand

======================================================================

#!/usr/bin/ruby -w
STDOUT.sync = true

require ‘socket’

SERVER_PORT = 7272
CLIENT_PORT = 7373

SERVER_HOST = ‘localhost’
CLIENT_HOST = ‘localhost’

PACKET_LENGTH = 64

SLEEP_TIME = 3 #seconds

MESSAGE = “I say, boy, I resemble that remark!”

class AbstractDaemon

def initialize(to_host, send_port, recv_port)
   @send_port = send_port
   @recv_port = recv_port
   @host = to_host
   @recv_socket = UDPSocket.new
   print "Listening on port: #{@recv_port}..."
   @recv_socket.bind(0, @recv_port)
   puts 'ok'
   @send_socket = UDPSocket.new
   print "Listening on port: #{@send_port}..."
   @send_socket.connect(0, @send_port)
   puts 'ok'
   do_stuff
end

def do_stuff
   raise Exception.new("Dummy method not implemented")
end

def send
   puts "Sending message: #{MESSAGE}"
   @send_socket.syswrite(MESSAGE)
end

def receive
   packet,address = *@recv_socket.recvfrom(PACKET_LENGTH)
   puts "Received message: #{packet}"
end

def pause
   print "Sleeping"
   SLEEP_TIME.times do
      print '.'
      sleep(1)
   end
   puts ""
end

end

class Server < AbstractDaemon

def initialize
   super(CLIENT_HOST, CLIENT_PORT, SERVER_PORT)
end

def do_stuff
   while true
      receive
      send

pause

   end
end

end

class Client < AbstractDaemon

def initialize
   super(SERVER_HOST, SERVER_PORT, CLIENT_PORT)
end

def do_stuff
   while true
      send
      receive

pause

   end
end

end

if ARGV[0] == ‘server’
Server.new
elsif ARGV[0] == ‘client’
Client.new
else
puts “Usage: #{$0} <client | server>”
end

From: “John C.” [email protected]

If I have a pair of Win2k Ruby processes bouncing UDP packets back and
forth…

After awhile one of them dies with Errno::ENOTCONN

The code works under Linux but not under Win2k, neither on ruby-1.8.6
nor 1.8.7.

Any guesses? Suggestions? Workarounds?

Replaced connect/syswrite, with send:

— john_carter_udp_enotconn.orig.rb 2008-09-09 23:27:04.491375000
-0700
+++ john_carter_udp_enotconn.rb 2008-09-09 23:27:50.975750000 -0700
@@ -28,7 +28,6 @@
puts ‘ok’
@send_socket = UDPSocket.new
print “Listening on port: #{@send_port}…”

  •   @send_socket.connect(0, @send_port)
      puts 'ok'
      do_stuff
    

    end
    @@ -39,7 +38,7 @@

    def send
    puts “Sending message: #{MESSAGE}”

  •   @send_socket.syswrite(MESSAGE)
    
  •   @send_socket.send(MESSAGE, 0, @host, @send_port)
    

    end

    def receive

Hope this helps,

Bill

Any guesses? Suggestions? Workarounds?
On Wed, 10 Sep 2008, Bill K. replied:
Replaced connect/syswrite, with send:

I thought, hmm, I’m pretty sure thats what I tried first…

Anyhoo, I’ll try your suggestion and…

…it worked!

Hope this helps,

So I went back to the original code and saw we had…
UDPSocket.open.send

Ping! Light goes on! Everytime we do UDPSocket.open we open an fd and
don’t close it.

The mystik Errno::ENOTCONN arises because the open failed (silently)
because we had run out of file handles!

Thanks!

John C. Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : [email protected]
New Zealand