title: Node.js UDP broadcast works on loopback, not across WiFi
body: <p>Trying to "find" my RaspberryPi on the local WiFi by having it broadcast its IP via a datagram. New to this, but seems like it should work:</p>
  
  <p>Broadcast message:</p>
  
  <pre><code>var Lighthouse = require('../lib/lighthouse.js');
  var lh = new Lighthouse();
  lh.startBroadcasting();
  </code></pre>
  
  <p>Listen for a message:</p>
  
  <pre><code>lh.listen();
  </code></pre>
  
  <p>Both NodeJS 6.7.0</p>
  
  <p>Full code:</p>
  
  <pre><code>var Netmask = require('netmask').Netmask
  var dgram = require('dgram');
  var os = require('os');
  
  var lighthouse = function Lighthouse() {
    this.timer = null;
    this.interval = 1;
    this.port = 3001;
    this.server = dgram.createSocket({type: "udp4", reuseAdr: true});
  }
  
  lighthouse.prototype.listen = function() {
    var self = this
  
    self.server.on('listening', () =&gt; {
      var address = self.server.address();
      console.log(`server listening ${address.address}:${address.port}`);
    });
  
    self.server.on('message', (msg, rinfo) =&gt; {
      console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
    });
  
    self.server.on('error', (err) =&gt; {
      console.log(`server error:\n${err.stack}`);
      server.close();
    });
  
    self.server.on('close', (err) =&gt; {
      console.log(`server close:\n${err.stack}`);
    });
  
    self.server.bind(self.port);
  }
  
  lighthouse.prototype.startBroadcasting = function() {
    var self = this;
  
    self.address = false;
    self.mask = false;
  
    var ifaces = os.networkInterfaces();
    Object.keys(ifaces).forEach(function (ifname) {
      ifaces[ifname].forEach(function (iface) {
        if ('IPv4' !== iface.family || iface.internal !== false) {
          return;
        }
  
        self.address = iface.address
        self.mask = iface.netmask
      });
    });
  
    if (self.address &amp;&amp; self.mask) {
      if (self.timer) {
        clearInterval(self.timer);
      }
  
      self.message = new Buffer("{server: '" + self.address + "'}");
  
      block = new Netmask(self.address + '/' + self.mask);
      self.braodcast_address = block.broadcast;
  
      console.log(`Broadcasting to: ${self.braodcast_address}:${self.port}`);
      console.log(String(self.message));
    }
  
    self.server.bind(function() {
      self.server.setBroadcast(true);
      self.timer = setInterval(function() {
        self.rebroadcast();
      }, self.interval * 1000);
    });
  }
  
  lighthouse.prototype.rebroadcast = function() {
    var self = this;
  
    if (self.message) {
      self.server.send(self.message, 0, self.message.length, self.port, self.broadcast_address, function() {
        console.log(`Sent message: ${self.message}`);
      });
    }
  }
  
  module.exports = lighthouse;
  </code></pre>
  
  <p>This is the output when the client and server run on the same machine (either machine):</p>
  
  <pre><code>00:20 $ node debug/broadcast.js 
  Broadcasting to: 10.0.1.255:3001
  {server: '10.0.1.7'}
  Sent message: {server: '10.0.1.7'}
  Sent message: {server: '10.0.1.7'}
  Sent message: {server: '10.0.1.7'}
  Sent message: {server: '10.0.1.7'}
  
  00:20 $ node debug/listen.js 
  server listening 0.0.0.0:3001
  server got: {server: '10.0.1.7'} from 127.0.0.1:50864
  server got: {server: '10.0.1.7'} from 127.0.0.1:50864
  server got: {server: '10.0.1.7'} from 127.0.0.1:50864
  server got: {server: '10.0.1.7'} from 127.0.0.1:50864
  </code></pre>
  
  <p>Seems to make contact, however when on separate machines, the listening side stops with just <code>server listening 0.0.0.0:3001</code></p>
  
  <p>Is broadcast the wrong thing to do here? <a href="https://stackoverflow.com/questions/9422522/udp-broadcasting-system-wont-communicate-on-separate-computers">This answer</a> seems to suggest it should be non-broadcast multicast. Maybe the AirPort router just blocks messages like this. tcpdump like <code>sudo tcpdump -n udp port 3001</code> seems to show nothing.</p>