rubyでマルチキャスト受信する方法

このQ&Aのポイント
  • WinXP、ruby1.8.6環境でマルチキャスト受信する方法を探しています。
  • require 'socket'やIPAddrクラスを使用してマルチキャスト受信するプログラムを作成しましたが、エラーが発生して実行できません。
  • Socket::IP_ADD_MEMBERSHIPの定数が見つからないようです。設定が必要なのでしょうか。
回答を見る
  • ベストアンサー

rubyでマルチキャスト受信するには

WinXP、ruby1.8.6環境で、マルチキャスト受信するプログラムを作ろうと思い、Webの情報を探して以下のようにしてみました。 require "socket" require "ipaddr" s = UDPSocket.open() s.bind("0.0.0.0", 10000) mreq = IPAddr.new("X.X.X.X").hton + IPAddr.new("0.0.0.0").hton s.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, mreq) p s.recv(65535) s.close X.X.X.Xはマルチキャストアドレスです。しかし、これを実行すると、「uninitialized constant Socket::IP_ADD_MEMBERSHIP (NameError)」となってしまい、実行できません。 なにか設定が必要なのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

少なくともWindows版のものではIP_ADD_MEMBERSHIPは定義されてないようです。 irb(main):016:0> Socket.constants.grep(/IP/) => ["AF_IPX", "IPPROTO_MAX", "IPPROTO_ICMP", "IPPROTO_UDP", "PF_IPX", "IPPORT_RESERVED", "IPPROTO_IGMP", "IPPROTO_IDP", "IPPORT_USERRESERVED", "IPPROTO_GGP", "IPPROTO_ND", "IPPROTO_TCP", "IPPROTO_RAW", "IPPROTO_IP", "IPPROTO_PUP"] Winsockコントロールを使用してマルチキャスト通信 - 教えて!goo http://oshiete1.goo.ne.jp/qa2176336.html この辺を見ると自分でがんばるしかないんじゃないでしょうか

lakings
質問者

お礼

早速の回答ありがとうございます。引用していただいたURLを見ると、Winsockヘッダファイルを参照させて解決していたとのことですが、rubyでも同じようなことができるのでしょうか。 また、IP_ADD_MEMBERSHIPの定義は5か12だろうと思われたので、setsockoptに直接指定してみましたが、 s.setsockopt(Socket::IPPROTO_IP, 5, mreq)とすると以下のエラー 「'setsockopt':getsockoptまたはsetsockoptの呼び出しで指定されたオプションまたはレベルは、不明か、無効か、あるいはサポートされていません。(Errno::ENOPROTOOPT)」、 s.setsockopt(Socket::IPPROTO_IP, 12, mreq)とすると以下のエラー 「'setsockopt':要求したアドレスのコンテキストが無効です。(Errno::EADDRNOTAVAIL)」 となってしまいました。

関連するQ&A

  • Winsockコントロールを使用してマルチキャスト通信

    まずは環境を WindowsXPSP2、VisualBasic6.0SP6です。 目的はサーバがマルチキャスト配信しているのを VBのクライアントがWinsockコントロールを使用して受信する方法を教えていただきたいのです。 Winsockコントロールを使用してUDPでの通信ができたのですが WinsockコントロールにはCの「setsockopt」に該当する命令が無い(わからない)のです。 Winsockコントロールで実現できないのであれば winsockのAPIを使用する方法でもかまわないのですが APIの情報も見つからず困っています。 APIを実装しても「IPPROTO_IP」「IP_ADD_MEMBERSHIP」などの定数の定義の情報がなくわからないのです。 これらの情報が載っているページや、解説しているページがあればお教えください。 または実装方法を知っておられるならお教えください。 よろしくお願いします。

  • ruby ldapライブラリが利用できない

    Rubyでldapを利用したいと思っているのですがうまくいかず悩んでいます。 下記よりruby-ldap.x.x.x.tar.gz をダウンロードしました。 ※最新のバージョン以外も試しています。 <http://ruby-ldap.sourceforge.net/> #!/usr/bin/ruby require "ldap"  ←/usr/lib/ruby/1.8/netldap.rb を指定 LDAP::Conn.new($ホスト、$ポート) と実行すると接続時に下のエラー内容が出ます。 "uninitialized constant LDAP (NameError)" 書籍、WEBを参考にしてスクリプトを組んだのですが、どこが問題なのかトレースできません。 もしお分かりの方がおりましたらお教えください。

  • 【Ruby】マルチスレッドでなくマルチプロセスで

    以下の様なプログラムをマルチスレッドでなくマルチプロセスで実現したいです。 #!/usr/bin/ruby require 'thread' q=Queue.new data=%w(a * * * b * * c * * d * *) data.each do |d| q.push d end (1..4).each do |n| Thread.start { while 1 do d=q.shift break if d!='*' end puts n.to_s+' '+d.to_s }.join end rubyのバーションは ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin10.0] です。バージョンをあげる事は、できれば避けたいです。 実際には上記プログラムの【puts n.to_s+' '+d.to_s】してる所は、ネットに繋いで云々の時間のかかる処理なのですが、まったくパラレルに行なっている様子が無いので、マルチプロセス化したら早くなるかなと思いました。 子プロセスを生成して親プロセスとはパイプで繋いで、、などとするのかなあと試行錯誤したのですが、どうもうまくできません。 ご指導の程、よろしくお願い申し上げます。

    • ベストアンサー
    • Ruby
  • c言語のチャットプログラムのsendとrecv

    現在、複数のクライアントからサーバーにメッセージを送りサーバーからクライアントにメッセージを送るというものを作成しているのですが、クライアントからサーバーにはメッセージを送れるのですが、サーバー側からクライアント1人にしか送れず、クライアント全員にメッセージを送信できませんので、よろしければアドバイスをお願いします サーバーのプログラム インクルード省略 #define BUF_LEN 256 typedef struct CLIENT_INFO { char hostname[BUF_LEN]; char ipaddr[BUF_LEN]; int port; time_t last_access; } CLIENT_INFO; CLIENT_INFO client_info[FD_SETSIZE]; int listening_socket; struct sockaddr_in sn; int accept_new_client(int sock){ int len; int new_socket; struct hostent *peer_host; struct sockaddr_in peer_sin; len = sizeof(sn); new_socket = accept(listening_socket, (struct sockaddr *)&sn, &len); if ( new_socket == -1 ){ perror("accept"); exit(1); } if ( new_socket > FD_SETSIZE-1 ){ return -1; } len = sizeof(peer_sin); getpeername(new_socket, (struct sockaddr *)&peer_sin, &len); peer_host = gethostbyaddr((char *)&peer_sin.sin_addr.s_addr, sizeof(peer_sin.sin_addr), AF_INET); strncpy(client_info[new_socket].hostname, peer_host->h_name, sizeof client_info[new_socket].hostname); strncpy(client_info[new_socket].ipaddr, inet_ntoa(peer_sin.sin_addr), sizeof client_info[new_socket].ipaddr); client_info[new_socket].port = ntohs(peer_sin.sin_port); time(&client_info[new_socket].last_access); printf("接続: %s (%s) ポート %d ディスクリプタ %d 番\n", client_info[new_socket].hostname, client_info[new_socket].ipaddr, client_info[new_socket].port, new_socket); return new_socket; } int read_and_reply(int sock){ int read_size; char buf[BUF_LEN]; read_size = read(sock, buf, sizeof(buf)-1); if ( read_size == 0 || read_size == -1 ){ printf("%s (%s) ポート %d ディスクリプタ %d 番からの接続が切れました。\n", client_info[sock].hostname, client_info[sock].ipaddr, client_info[sock].port, sock); close(sock); client_info[sock].last_access = 0; } else { buf[read_size] = '\0'; printf("%s (%s) ポート %d ディスクリプタ %d 番からのメッセージ: %s", client_info[sock].hostname, client_info[sock].ipaddr, client_info[sock].port, sock, buf); write(sock, buf, strlen(buf)); time(&client_info[sock].last_access); } return read_size; } int main(){ fd_set target_fds; fd_set org_target_fds; int sock_optval = 1; int port = 5000;    listening_socket = socket(AF_INET, SOCK_STREAM, 0); if ( setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR, &sock_optval, sizeof(sock_optval)) == -1 ){ perror("setsockopt"); exit(1); }  sn.sin_family = AF_INET; sn.sin_port = htons(port); sn.sin_addr.s_addr = htonl(INADDR_ANY); if ( bind(listening_socket, (struct sockaddr *)&sn, sizeof(sn)) < 0 ){ perror("bind"); exit(1); }   if ( listen(listening_socket, SOMAXCONN) == -1 ){ perror("listen"); exit(1); printf("ポート %d を見張ります。\n", port);   FD_ZERO(&org_target_fds); FD_SET(listening_socket, &org_target_fds);   while (1){ int i; time_t now_time; struct timeval waitval; waitval.tv_sec = 2; waitval.tv_usec = 500;  memcpy(&target_fds, &org_target_fds, sizeof(org_target_fds));  select(FD_SETSIZE, &target_fds, NULL, NULL, &waitval);  for ( i=0 ; i<FD_SETSIZE ; i++ ) { if ( FD_ISSET(i, &target_fds) ) { printf("ディスクリプタ %d 番が読み込み可能です。\n", i); if ( i == listening_socket ) { int new_sock; new_sock = accept_new_client(i); if ( new_sock != -1 ) { FD_SET(new_sock, &org_target_fds); } } else {int read_size;  read_size = read_size; read_size = read_and_reply(i); if ( read_size == -1 || read_size == 0 ) { FD_CLR(i, &org_target_fds); } } } } time(&now_time); for ( i=0 ; i<FD_SETSIZE ; i++){ if ( ! FD_ISSET(i, &org_target_fds) ) continue; if ( i == listening_socket ) continue; if ( now_time-60 > client_info[i].last_access ) { close(i); FD_CLR(i, &org_target_fds); } } } close(listening_socket); FD_CLR(i, &org_target_fds); } }

  • Ruby on Railsの環境構築

    どうにも困り果てております。 少し面倒な質問となってしまいますが、お答え頂けると助かります。 現在、Railsを利用したWEBアプリケーションを作成しようと、Railsの勉強をしているのですが、環境構築の段階でつまづいてしまいました。 具体的には、TerminalでRails sコマンド実行しても、WEBrickが起動せず、 /opt/local/lib/ruby/gems/1.8/gems/bundler-1.0.22/lib/bundler/rubygems_integration.rb:183:in `stub_source_index170': uninitialized constant Gem::SourceIndex (NameError) のようなメッセージが表示されてしまいます。 Mac OS X Lion 10.7.5を使用しております。 また、Terminalで -vコマンドを利用して確かめた所、 ruby 1.8.7 (2012-02-08 patchlevel 358) [i686-darwin11] gem 2.1.11 MacPorts 2.2.1 Rails 3.2.2 Xcode 4.2.1 が確認出来ました。 Terminalを使っての作業が初めてであったため、うまく説明出来ていない部分もあるとは思いますが、ご指導頂けると幸いです。 よろしくお願い致します。

    • ベストアンサー
    • Ruby
  • Rubyでメタ検索プログラムを見よう見まねで書いていますが、結果がバイナリ文字列で表示されます。

    Rubyで下記のようなプログラムを書いています。ある検索サイトに対してメタサーチ的なものを実現したいと思い、見よう見まねで作っています。問題は結果が出るものの、日本語で本来出るべき結果部分がバイナリ文字列で表示されます。例えば、?216?241?227?303?201o?202?277といった感じです。おそらく初歩的な質問になってしまうと思いますが、教えていただけると助かります #!/usr/bin/ruby require "socket" require "cgi" c = CGI.new text = c["t"] s = TCPSocket.new("www.xxx.com", 80) s.write "GET /xxx/index.php?word_in=xxx HTTP/1.0?r?n?r?n" print "Content-Type: text/html?n?n" result=s.read.split(/?<li?>/) p result[1] print "<br>" print "</body></html>"

  • trim()メソッドの使用方法とキャストの仕方について

    こんばんは、今回はtrim()メソッドの使用方法とキャストの方法についてお伺い致します。 trimメソッドを使用して文字列の前後の空白を削除したいのですが、 通常 String str = " 「こんにちは」"; str = str.trim(); とコーディングしコンパイルして表示するとちゃんと「こんにちは」となるのすですが、これが ArrayList list = new ArrayList(); BufferedReader br= new BufferedReader(new FileReader(Test.txt); while((str = br.readLine()) !=null){ str = str.trim(); list.add(str); } br.close(); とコーディングしコンパイルは通るのですが、 「こんにちは」のままで"「"の前にある空白が削除されてません。 私なりに「型」の違いでが原因ではないかと思い、java.io.ArrayList型からjava.lang.String型へキャストしようとしているのですが、コンパイルエラーが出てしまします。 プログラムコードは ArrayList list = new ArrayList(); String s; s = (String)list; としています。 エラー内容は ScheduleControlCall.java:142: 変換できない型 出現: java.util.ArrayList 要求: java.lang.String s = (String)list; ^ エラー 1 個 となっています。 度々ですが、ご指導お願い致します。

    • ベストアンサー
    • Java
  • 色の指定で配列を使いたい

    ASP.NETで棒グラフを描いています。 3本の棒があったとして、今までは、 ------------------------------------------------ g.FillRectangle(New SolidBrush(Color.Blue), x, y, width, height) g.FillRectangle(New SolidBrush(Color.Green), x, y, width, height) g.FillRectangle(New SolidBrush(Color.Red), x, y, width, height) ------------------------------------------------ このように書いていたのですが、 色の部分を配列にしたいと考えています。 ------------------------------------------------ Dim BrCol As New ArrayList BrCol.Add("Blue") BrCol.Add("Green") BrCol.Add("Red") For i = 0 to 2 g.FillRectangle(New SolidBrush(BrCol(0)), x, y, width, height) Next ------------------------------------------------ これではエラーになります("指定されたキャストは有効ではありません。") どのように書けばよいでしょうか? よろしくお願いします。

  • iphoneアプリ実行結果について

    これを実行すると、iphoneの画面には何か表示されるのですか?真っ白とかですかね…。 #import<CoreFoundation/CoreFoundation.h> #import <sys/socket.h> #import <netinet/in.h> CFSocketRef socket = CFSocketCreate(NULL, PF_INET, SOCK_DGRAM, IPPROTO_UDP, kCFSocketNoCallBack, NULL, NULL); struct sockaddr_in addr; addr.sin_len = sizeof(struct sockaddr_in); addr.sin_family = AF_INET; addr.sin_addr.s_addr = addr.sin_addr.s_addr = inet_addr(''192.168.0.3''); addr.sin_port = htons(3054); CFDataRef address = CFDataCreate(NULL, (UInt8*)&addr, sizeof(struct sockaddr_in)); UInt8 message[] = {0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x02, 0x44, 0x33, 0x05}; CFDataRef data = CFDataCreate(NULL, (UInt8*)message, sizeof(message)); CFSocketSendData(socket, address, data, 3); CFRelease(socket); CFRelease(address); CFRelease(data);

  • ruby mechanize アクセス出来ない

    https://login.ocn.ne.jp/auth/s2016/pc/AuthLoginDisplay.action このサイトにRubyのmechanizeからログインしたいのですが、 そもそもここにアクセスできていないようです。 .actionというのはhtmlと違ってアクセスできないのでしょうか。 以下、コードと出力です。 # -*- encoding: utf-8 -*- require 'rubygems' require 'mechanize' agent = Mechanize.new page = agent.get('https://login.ocn.ne.jp/auth/s2016/pc/AuthLoginDisplay.action') pp page 出力 #<Mechanize::Page {url #<URI::HTTPS:0x007f989240a150 URL:https://login.ocn.ne.jp/auth/s2016/pc/AuthLoginDisplay.action>} {meta_refresh} {title "システムエラー"} {iframes} {frames} {links #<Mechanize::Page::Link "ヘルプ" "http://www.ocn.ne.jp/login/mb/index.html"> #<Mechanize::Page::Link "著作権について" "http://mobile.ntt.com/m/copyright.html"> #<Mechanize::Page::Link "プライバシーポリシー" "http://506506.ntt.com/mbl/privacy/s_policy01.html"> #<Mechanize::Page::Link "→OCNトップ" "http://www.ocn.ne.jp"> #<Mechanize::Page::Link "NTT Communications" "http://www.ntt.com/"> #<Mechanize::Page::Link "著作権について" "http://www.ntt.com/COPYRIGHT/"> #<Mechanize::Page::Link "プライバシーポリシー" "http://www.ocn.ne.jp/privacy-policy/"> #<Mechanize::Page::Link "NTTコミュニケーションズ" "http://www.ntt.com/">} {forms}> 以上

    • ベストアンサー
    • Ruby

専門家に質問してみよう