Daniel Brockman wrote:
> Joel VanderWerf <vjoel / path.berkeley.edu> writes:
> 
> 
>>Why should connecting a UDPSocket to _another_ broadcast
>>port interfere with receiving?
> 
> 
> CONNECT(2)        Linux Programmers Manual        CONNECT(2)
> 
> NAME
>        connect - initiate a connection on a socket
> 
> SYNOPSIS
>        #include <sys/types.h>
>        #include <sys/socket.h>
> 
>        int connect(int sockfd, const struct sockaddr
>        *serv_addr, socklen_t addrlen);
> 
> DESCRIPTION
>        The file  descriptor sockfd  must refer to  a socket.
>        If  the  socket  is   of  type  SOCK_DGRAM  then  the
>        serv_addr address  is the address  to which datagrams
>        are sent by default,  and the only address from which
>        datagrams are received.
> 
>        [...]
> 

Hm, so linux connect() implies bind() on UDP sockets?

Then is ruby doing something funny on top of the linux socket API? Why
does the following code work? (It sets up two sockets that connect to
the port each other is listening on, which should not be possible, if I
understand man connect.)

require 'socket'

Socket.do_not_reverse_lookup = true

addr = '127.0.0.1'

socks = (0..1).map {UDPSocket.open()}
socks.each {|s| s.bind(addr, 0)}
ports = socks.map {|s| s.addr[1]}

socks.each_with_index {|s,i| s.connect(addr, ports[1-i])}
puts socks.map{|s| [s.addr, s.peeraddr].inspect}

s0, s1 = socks

t0 = Thread.new do
  puts "s1 received: #{s1.recv(100)}"
end
sleep 0.1

s0.send "foo", 0

t0.join


t1 = Thread.new do
  puts "s0 received: #{s0.recv(100)}"
end
sleep 0.1

s1.send "bar", 0

t1.join

__END__

output:

[["AF_INET", 33223, "127.0.0.1", "127.0.0.1"], ["AF_INET", 33224,
"127.0.0.1", "127.0.0.1"]]
[["AF_INET", 33224, "127.0.0.1", "127.0.0.1"], ["AF_INET", 33223,
"127.0.0.1", "127.0.0.1"]]
s1 received: foo
s0 received: bar

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