0

I'm using this bit of code to send and receive data, problem is I don't receive anything..

Code:

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

If I'm sending the exact same message with Ruby's UDPSocket I do receive data (from the UDPSocket, not from EM)..

Can someone tell me what I'm doing wrong here?

Thanks

Tim Baas
  • 6,035
  • 5
  • 45
  • 72

2 Answers2

0

First problem: use Connection#send_datagram instead of Connection#send_data

"DO NOT call send_data from a datagram socket outside of a EventMachine::Connection#receive_data method. Use EventMachine::Connection#send_datagram." http://rubydoc.info/gems/eventmachine/1.0.0/EventMachine#open_datagram_socket-class_method

Second problem appears to be related to using a multicast address. The following works for me.

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}"
}
simulacre
  • 1,223
  • 8
  • 7
  • Thanks for your answer, I also tried the send_datagram, didn't work for me either.. Probably because of the MultiCast address.. What do you mean by works for me, do you find UPnP devices in your home network with this? I will test this when I get home! PS: What's with the `gsub` in the MSEARCH message? Thanks! – Tim Baas Nov 09 '12 at 08:30
  • This indeed works.. But for UPnP I need to work on 239:255:255:250:1900.. So, I don't know why it doesn't work with that IP, but I need anothor solution to move on.. – Tim Baas Nov 12 '12 at 08:39
0

This is how i got EventMachine to setup a datagram socket and listen for SSDP announcments.

Change:

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

To:

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

You have to actually bind to your ip address and not the multicast address. Then add a constructor to your client class where you tell the socket to join the multicast group for 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


.....
Patrik
  • 255
  • 3
  • 11