How to broadcast UDP packets

I’m trying to use ruby to immitate some C code that broadcasts UDP
packets, but I can only seem to receive packets that are sent to a
specific interface address, not to a broadcast address. Here are the
sender and receiver:

==== sender.rb ====
require ‘socket’

port = 1234

#host = "localhost"
host = “192.168.1.3”

#host = “”
#host = “255.255.255.255”

socket = UDPSocket.open
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)

loop do
socket.send(“sample data”, 0, host, port)
sleep 0.1
end

···

====

==== receiver.rb ====
require ‘socket’

port = 1234

#host = "localhost"
host = “192.168.1.3”

#host = “”
#host = “255.255.255.255”
#host = “”
#host = nil

socket = UDPSocket.open
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)

socket.bind(host, port)
p socket.recvfrom(20)

As the two programs are written, the receiver prints out “sample data”.
That’s also the case when both programs use

host = “localhost”

But for any combination of the broadcast hosts (e.g., “” and
""), the receiver doesn’t get the packet.

Any help is appreciated.

Try “0.0.0.0” as host in your server.

···

On Thu, 2004-01-22 at 22:38, Joel VanderWerf wrote:

Any help is appreciated.


lambda {|c| lambda {|f| f[f] } [lambda {|f| c[lambda { |x| f[f] }]}]}

Have you tried binding to the network broadcast address rather than the
global broadcast address ?

e.g. 192.168.1.255

Also, there are anycast address spaces. What address is the UDP packet
broadcast on ? 255.255.255.255

Joel VanderWerf wrote:

···

I’m trying to use ruby to immitate some C code that broadcasts UDP
packets, but I can only seem to receive packets that are sent to a
specific interface address, not to a broadcast address. Here are the
sender and receiver:

==== sender.rb ====
require ‘socket’

port = 1234

#host = “localhost”
host = “192.168.1.3”

#host = “”
#host = “255.255.255.255”

socket = UDPSocket.open
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)

loop do
socket.send(“sample data”, 0, host, port)
sleep 0.1
end

==== receiver.rb ====
require ‘socket’

port = 1234

#host = “localhost”
host = “192.168.1.3”

#host = “”
#host = “255.255.255.255”
#host = “”
#host = nil

socket = UDPSocket.open
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)

socket.bind(host, port)
p socket.recvfrom(20)

As the two programs are written, the receiver prints out “sample
data”. That’s also the case when both programs use

host = “localhost”

But for any combination of the broadcast hosts (e.g., “”
and “”), the receiver doesn’t get the packet.

Any help is appreciated.

Florian,

Would you explain your .sig? It makes my brain itch. :slight_smile:

Thanks,
Hal

lambda {|c| lambda {|f| f[f] } [lambda {|f| c[lambda { |x| f[f][x] }]}]}

PS - The only way I can scratch it is to think about sandpaper. - HF

Florian Frank wrote:

···

On Thu, 2004-01-22 at 22:38, Joel VanderWerf wrote:

Any help is appreciated.

Try “0.0.0.0” as host in your server.

That’s it. Thanks a lot, Florian.

Btw, nil also works as the host for the server, as below (I guess it’s a
ruby convenience):

socket = UDPSocket.open
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
socket.send(“sample data”, 0, nil, port) # nil or “0.0.0.0”

Not only your brain! :wink:

It’s the (applicate order) Y-Combinator that’s used to implement
recursion in lambda calculus. It has the property Y(f) = f(Y(f)),
that means that it returns the fixed point of the given function
f.

If you define it like this

Y = lambda { |c|
lambda { |f| f[f] } [
lambda { |f|
c[lambda { |x| f[f] }]
}
]
}

you can define arbitrary recursive functions with it like
the faculty function (here applied to 10)

Y[
lambda { |fak| lambda { |n| n == 0 ? 1 : n * fak[n-1] } }
][10]

or Fibonacci numbers

Y[
lambda { |fib| lambda { |n| n <= 1 ? 1 : fib[n - 2] + fib[n - 1] } }
][10]

You don’t have to assign this thingy to Y. You can use it
in a whole expression; here is the faculty function again:

lambda { |y, g| y[g] } [
lambda { |c|
lambda { |f| f[f] } [
lambda { |f|
c[lambda { |x| f[f] }]
}
]
},
lambda { |fak|
lambda { |n| n == 0 ? 1 : n * fak[n-1] }
}
][10]

To define Y is an important step, if you want to prove that the
lambda calculus and turing machine computability are equally
powerful. You can even eliminate the conditional statement,
the numbers (they can be translated to church numerals) and
arithmetic from the expression above and use lambda abstraction
and functional application instead. It’s also possbible
to define pairs and lists that consist of pairs that way.

I hope this explanation helped a bit. If it didn’t: I think
there are a lot of texts who derive this combinator in Scheme
or LISP to be found in the web, that can explain this better than
I can. BTW: Scheme would also make a good LOTY.

···

On Fri, 2004-01-23 at 00:37, Hal Fulton wrote:

Would you explain your .sig? It makes my brain itch. :slight_smile:


lambda {|c| lambda {|f| f[f] } [lambda {|f| c[lambda { |x| f[f] }]}]}

That’s usually called the “factorial” function . . .

Cool stuff. I don’t usually think of Ruby as a language for
higher-order functions . . .

-Mark

···

On Fri, Jan 23, 2004 at 09:52:47AM +0900, Florian Frank wrote:

the faculty function (here applied to 10)

Florian Frank wrote:

Would you explain your .sig? It makes my brain itch. :slight_smile:

Not only your brain! :wink:

It’s the (applicate order) Y-Combinator that’s used to implement
recursion in lambda calculus. It has the property Y(f) = f(Y(f)),
that means that it returns the fixed point of the given function
f.

I was skimming through the threads in the mail list. Imagine my
surprise to find a discussion of the dreaded applicative order Y
combinator in a thread titled “how to broadcast UDP packets”. Cool.

I played around with the Y combinator some years ago, and traces of that
conversation still remain on some mailing list archives. It started
when someone posted a a version of the Y combinator in Perl (shudder).
I responded with a version in Java (double shudder). The java version
didn’t fit so nicely in one line however.

If you are interested in the java version you can find it here:
http://www.clug.org//ml/archive/programming/1998-11/msg00014.html
But watch out, it is more likely to make your brain explode than itch.

I even wrote out a commented derivation of the Y-combinator. I swear I
understand each individual step of the derivation, but fitting the
entire thing in my head at once is difficult. The derivation in here:
http://www.clug.org//ml/archive/programming/1998-11/msg00028.html

···

On Fri, 2004-01-23 at 00:37, Hal Fulton wrote:


– Jim Weirich jweirich@one.net http://onestepback.org

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

“Jim Weirich” jweirich@one.net wrote in message

I even wrote out a commented derivation of the Y-combinator. I swear I
understand each individual step of the derivation, but fitting the
entire thing in my head at once is difficult. The derivation in here:
http://www.clug.org//ml/archive/programming/1998-11/msg00028.html

Thank you very much, Jim.
Exactly what I wanted … now I have some hope of understanding that beast
:wink:

– shanko

If you are interested in the java version you can find it here:
http://www.clug.org//ml/archive/programming/1998-11/msg00014.html
But watch out, it is more likely to make your brain explode than itch.

Ah, you’re using the anonymous inner classes trick. You can even
implement closures (with shared data) that way in Java. It’s very
verbose and also looks pretty ugly though:

public class Closure {

 public static void main (String args[]) {
	final int a[] = new int[1];
	Runnable add = new Runnable() {
		public void run() {
			a[0] += 1;
			System.out.println("I am " + a[0] + ".");
		}
	};
	Runnable sub = new Runnable() {
		public void run() {
			a[0] -= 1;
			System.out.println("I am " + a[0] + ".");
		}
	};
	add.run();
	add.run();
	sub.run();
 }

}

I even wrote out a commented derivation of the Y-combinator. I swear
I understand each individual step of the derivation, but fitting the
entire thing in my head at once is difficult.
The derivation in here:
http://www.clug.org//ml/archive/programming/1998-11/msg00028.html

Cool. I’ve done a derivation in Scheme, too, because I did not
understand a more theoretical text on the subject. I the just
translated the solution I found into Ruby, which was pretty easy.

I think it’s important to do this step by step, at least once. Somehow
I felt that I’ve just understood something very important about the
nature of computation when I was done with it. It’s different to
explain, like some zen-like experience I figure. :wink:

lambda { |c| lambda { |f| f[f] } [ lambda { |f| c[lambda { |x| f[f]
} ] }] }

···

On 23.01.2004, at 09:00, Jim Weirich wrote: