|
require 'socket'
|
|
port = 10000
|
|
sai = Addrinfo.udp('::', port)
|
|
p [:server_listening_on, sai]
|
|
socket = Socket.new(sai.pfamily, sai.socktype, sai.protocol)
|
|
socket.ipv6only!
|
|
socket.bind(sai.family_addrinfo(sai.ip_address, port))
|
|
socket.setsockopt(:IPV6, Socket::IPV6_RECVPKTINFO, 1)
|
|
th = Thread.new {
|
|
r = IO.select([socket]).first.first
|
|
msg, sender_addrinfo, _, *controls = r.recvmsg_nonblock
|
|
p [:server_recvmsg_nonblock_output, msg, sender_addrinfo, controls]
|
|
pktinfo = controls.find {|c| c.cmsg_is?(:IPV6, :PKTINFO) }
|
|
args = [msg.reverse, 0, sender_addrinfo]
|
|
args << pktinfo if ARGV.last == 'pktinfo'
|
|
p [:server_response_sendmsg_args, args]
|
|
r.sendmsg *args
|
|
}
|
|
sleep 0.1
|
|
cai = Addrinfo.udp(ARGV.first, port)
|
|
cai.connect {|s|
|
|
s.sendmsg "foo"
|
|
raise "no response from #{cai.inspect}" unless IO.select([s], nil, nil, 10)
|
|
msg2, addr = s.recvmsg
|
|
p [:response_from_server, msg2, addr]
|
|
}
|