【Ruby】UDPマルチキャスト送信で Errno::EADDRNOTAVAIL
Mac を Snow Leopard 化してから、UDPマルチキャスト送信時に以下のエラーが起きるようになってしまいました。
Errno::EADDRNOTAVAIL: Can't assign requested address - sendto(2)
使用しているRubyのバージョンは 1.8.7 p174。
具体的なコードは以下の通りです(簡略化してます):
require 'ipaddr' # Multi-cast IP ip = "224.0.0.10" port = 9876 maddr = IPAddr.new(ip).hton + IPAddr.new('0.0.0.0').hton # UDPソケットオブジェクトを作る sock = UDPSocket.new sock.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR,1) sock.bind(ip, port) sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, maddr) # メッセージを送信 sock.send('hello', 0, ip, port).to_s
Leopard では問題なかったのになぜ??
小一時間を費やして試行錯誤した結果、マルチキャスト用のネットワークインターフェイスを指定してあげることで問題解決できることが分かりました。
改良版のコードは以下の通り:
require 'ipaddr' # Multi-cast IP ip = "224.0.0.10" port = 9876 maddr = IPAddr.new(ip).hton + IPAddr.new('0.0.0.0').hton # UDPソケットオブジェクトを作る sock = UDPSocket.new sock.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR,1) sock.bind(ip, port) sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, maddr) # IFを指定(この場合はループバック) sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_MULTICAST_IF, IPAddr.new('127.0.0.1').hton) # メッセージを送信 sock.send('hello', 0, ip, port).to_s
原因はよく分かりませんが、エラーメッセージから察するにネイティブコールでの問題のようですね。
差し当たりこの方法で解決できたので、Snow Leopard からの UDP Multicast で同様のエラーに遭遇された方は参考にしてみてください。
No comments
Jump to comment form | comments rss [?] | trackback uri [?]