UDP Socket problem

Hi there,

I try to write a comm program based on udp broadcasting protocol. I did the following:

SERVER:

require 'socket'
server = UDPSocket.open
server.bind('0.0.0.0', 4321)
while true do
  p server.recvfrom(10)
end

CLIENT

require 'socket'
socket = UDPSocket.open
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
socket.send("sample", 0, '255.255.255.255', 4321)

Now there are 2 problems:

1) the server will print out 2 line of data e.g.:
["sample", ["AF_INET", 1339, "XRFANG-OTM", "192.168.1.101"]]

but the client only sent one packet.

2) if the client send data more than 10 bytes, the server will crash! I don't know how to set the "recvfrom" so that it can receive ANY byte of data. i.e. when the client supplied more than the maximum wanted data for the server, the rest should be received on the next call to recvfrom, or at least, it should simply discard the excessive data, it must not crash the server anyway.

Thank you very much!

Shannon

I can't reproduce

CLIENT

moulon% ruby
require 'socket'
socket = UDPSocket.open
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
socket.send("sample", 0, '255.255.255.255', 4321)
socket.send("1234567890123456789012345678901234567890123456789012345678901234567890", 0, '255.255.255.255', 4321)
moulon%

SERVER

moulon% ruby
require 'socket'
server = UDPSocket.open
server.bind('0.0.0.0', 4321)
while true do
p server.recvfrom(10)
end
["sample", ["AF_INET", 47842, "moulon.inra.fr", "138.102.114.1"]]
["1234567890", ["AF_INET", 47842, "moulon.inra.fr", "138.102.114.1"]]
^C
-:5:in `recvfrom': Interrupt
  from -:5
moulon%

Guy Decoux

Shannon Fang wrote:

Hi there,

I try to write a comm program based on udp broadcasting protocol. I did the following:

SERVER:

require 'socket'
server = UDPSocket.open
server.bind('0.0.0.0', 4321)
while true do
p server.recvfrom(10)
end

CLIENT

require 'socket'
socket = UDPSocket.open
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
socket.send("sample", 0, '255.255.255.255', 4321)

Now there are 2 problems:

1) the server will print out 2 line of data e.g.:
["sample", ["AF_INET", 1339, "XRFANG-OTM", "192.168.1.101"]]

but the client only sent one packet.

Can't reproduce that. Does it happen repeatably? Does it happen if you do
   server.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
after opening the server socket?

I'm on WinXP, with ruby-1.8.2 from the installer.

2) if the client send data more than 10 bytes, the server will crash! I don't know how to set the "recvfrom" so that it can receive ANY byte of data. i.e. when the client supplied more than the maximum wanted data for the server, the rest should be received on the next call to recvfrom, or at least, it should simply discard the excessive data, it must not crash the server anyway.

I see that too:

server.rb:6:in `recvfrom': A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself. - recvfrom(2) (Errno::EMSGSIZE)
         from server.rb:6

That doesn't seem like winsock has correctly implemented UDP. Shouldn't recvfrom discard extra bytes?

Googling for "winsock udp broadcast" shows that others have found similar problems. Particularly:

http://forum.java.sun.com/thread.jspa?threadID=680096&messageID=3972638

I guess this means the receiver needs to (a) know the max size of legitimate data and (b) handle EMSGSIZE (at least logging an error, but maybe not exiting).

Useful to know. Thanks!

···

--
        vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

yuray@yuray:~/r$ ruby --version
ruby 1.8.2 (2004-12-25) [i686-linux]
yuray@yuray:~/r$ cat c.rb
require 'socket'
socket = UDPSocket.open
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
socket.send("sample1234567890", 0, '255.255.255.255', 4321) ### more
then 10

yuray@yuray:~/r$
yuray@yuray:~/r$ cat s.rb
require 'socket'
server = UDPSocket.open
server.bind('0.0.0.0', 4321)
while true do
  p server.recvfrom(10)
end

yuray@yuray:~/r$ ruby s.rb
["sample1234", ["AF_INET", 32783, "yuray.####.ru.", "172.20.1.33"]]

Works for me. Client and server was running on single machine.
What is ruby version?
Can you run the test client and server on single machine?
Can you test with a new clear ruby installation without any packages ?

Regards,
Yuri Kozlov

I run the program on winxp, is that causing problems???

I will test on linux, if anything interesting I will report.

thanks,
shannon

···

From: ts <decoux@moulon.inra.fr>
Reply-To: ruby-talk@ruby-lang.org
To: ruby-talk@ruby-lang.org (ruby-talk ML)
CC: ruby-talk@ruby-lang.org
Subject: Re: UDP Socket problem
Date: Fri, 25 Nov 2005 00:58:55 +0900

I can't reproduce

CLIENT

moulon% ruby
require 'socket'
socket = UDPSocket.open
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
socket.send("sample", 0, '255.255.255.255', 4321)
socket.send("1234567890123456789012345678901234567890123456789012345678901234567890", 0, '255.255.255.255', 4321)
moulon%

SERVER

moulon% ruby
require 'socket'
server = UDPSocket.open
server.bind('0.0.0.0', 4321)
while true do
p server.recvfrom(10)
end
["sample", ["AF_INET", 47842, "moulon.inra.fr", "138.102.114.1"]]
["1234567890", ["AF_INET", 47842, "moulon.inra.fr", "138.102.114.1"]]
^C
-:5:in `recvfrom': Interrupt
from -:5
moulon%

Guy Decoux

Hi,

I have tested this on my linux, it worked fine, but this problem do exist on both win2k (pro.) and winxp (home).

Any ideas?

thanks a lot!
shannon

···

From: ts <decoux@moulon.inra.fr>
Reply-To: ruby-talk@ruby-lang.org
To: ruby-talk@ruby-lang.org (ruby-talk ML)
CC: ruby-talk@ruby-lang.org
Subject: Re: UDP Socket problem
Date: Fri, 25 Nov 2005 00:58:55 +0900

I can't reproduce

CLIENT

moulon% ruby
require 'socket'
socket = UDPSocket.open
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
socket.send("sample", 0, '255.255.255.255', 4321)
socket.send("1234567890123456789012345678901234567890123456789012345678901234567890", 0, '255.255.255.255', 4321)
moulon%

SERVER

moulon% ruby
require 'socket'
server = UDPSocket.open
server.bind('0.0.0.0', 4321)
while true do
p server.recvfrom(10)
end
["sample", ["AF_INET", 47842, "moulon.inra.fr", "138.102.114.1"]]
["1234567890", ["AF_INET", 47842, "moulon.inra.fr", "138.102.114.1"]]
^C
-:5:in `recvfrom': Interrupt
from -:5
moulon%

Guy Decoux

This problem confirmed to be a winsock problem, not ruby's. tks! btw, I run ruby 1.8.2 on winxp.

shannon

···

From: "Yuri Kozlov" <kozlov.y@gmail.com>
Reply-To: ruby-talk@ruby-lang.org
To: ruby-talk@ruby-lang.org (ruby-talk ML)
Subject: Re: UDP Socket problem
Date: Fri, 25 Nov 2005 18:07:26 +0900

yuray@yuray:~/r$ ruby --version
ruby 1.8.2 (2004-12-25) [i686-linux]
yuray@yuray:~/r$ cat c.rb
require 'socket'
socket = UDPSocket.open
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
socket.send("sample1234567890", 0, '255.255.255.255', 4321) ### more
then 10

yuray@yuray:~/r$
yuray@yuray:~/r$ cat s.rb
require 'socket'
server = UDPSocket.open
server.bind('0.0.0.0', 4321)
while true do
  p server.recvfrom(10)
end

yuray@yuray:~/r$ ruby s.rb
["sample1234", ["AF_INET", 32783, "yuray.####.ru.", "172.20.1.33"]]

Works for me. Client and server was running on single machine.
What is ruby version?
Can you run the test client and server on single machine?
Can you test with a new clear ruby installation without any packages ?

Regards,
Yuri Kozlov