EventMachine不通过数据报套接字接收数据

时间:2012-11-08 21:40:50

标签: ruby sockets udp eventmachine

我正在使用这段代码发送和接收数据,问题是我没有收到任何东西..

代码:

US_HOST = "239.255.255.250"
US_PORT = 1900

module SSDP
  class Client < EventMachine::Connection
    def receive_data data
      p "Received some data:"
      p data
    end
  end
end

us = EM.open_datagram_socket US_HOST, US_PORT, SSDP::Client

us.send_data msg

def msg
<<-MSEARCH
M-SEARCH * HTTP/1.1\r
HOST: #{US_HOST}:#{US_PORT}\r
MAN: ssdp:discover\r
MX: 1\r
ST: ssdp:all\r
\r
MSEARCH
end

如果我使用Ruby UDPSocket发送完全相同的消息我执行接收数据(来自UDPSocket,而不是来自EM)..

有人能告诉我这里的错误吗?

由于

2 个答案:

答案 0 :(得分:0)

第一个问题:使用Connection#send_datagram代替Connection#send_data

“不要从EventMachine :: Connection#receive_data方法之外的数据报套接字调用send_data。使用EventMachine :: Connection#send_datagram。” http://rubydoc.info/gems/eventmachine/1.0.0/EventMachine#open_datagram_socket-class_method

第二个问题似乎与使用多播地址有关。以下适用于我。

require "eventmachine"

US_HOST = "127.0.0.1"
US_PORT = 1900

module SSDP
  class Client < EventMachine::Connection
    def receive_data data
      warn "recv: #{data.inspect}"
    end
  end
end

def msg
<<-MSEARCH.gsub(/^\s+/,"")
  M-SEARCH * HTTP/1.1\r
  HOST: #{US_HOST}:#{US_PORT}\r
  MAN: ssdp:discover\r
  MX: 1\r
  ST: ssdp:all\r
  \r
MSEARCH
end

EM.run {
  us = EM.open_datagram_socket(US_HOST, US_PORT, SSDP::Client)
  us.send_datagram(msg, US_HOST, US_PORT)
  warn  "sent: #{msg.inspect}"
}

答案 1 :(得分:0)

这就是我让EventMachine设置数据报套接字并监听SSDP通知的方法。

变化:

us = EM.open_datagram_socket(US_HOST, US_PORT, SSDP::Client)

要:

us = EM.open_datagram_socket('0.0.0.0', US_PORT, SSDP::Client)

您必须实际绑定到您的IP地址而不是多播地址。然后在您的客户端类中添加一个构造函数,您可以告诉套接字加入SSDP的多播组。

class Client < EventMachine::Connection

def initialize
  puts "Socket setup"
  set_sock_opt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, 
               IPAddr.new('239.255.255.250').hton +
               IPAddr.new('0.0.0.0').hton)
end


.....