title: Using ZEROMQ and NORM to multicast packets to a large number of WiFI devices
body: <p>I'm trying to send a file over a wireless network using ZeroMQ and the NORM protocol. I'm currently using the PUB/SUB pattern as that's the only pattern supported by NORM with ZeroMQ as far as I can tell. </p>
  
  <p>I've got it set up so that small messages are passed along just fine, but occasionally the receiver wont pick up a message. From that point messages are just dropped. This can occasionally be remedied by restarting either the Publisher or the Subscriber, but not every time. I've tried adjusting the about of bits sent and the time between each call to send to no avail. It looks like I can receive about 20-60 multicast messages before the connection becomes unstable. If i use the same code but set it up with TCP the connection is much more reliable, on the order of thousands of messages before an error occurs.</p>
  
  <p>I've tried implementing a wrapper class to restart the subscribers after a certain period of inactivity - that didn't work. Neither does setting socket.recv(zmq.NOBLOCK) inside a while loop. </p>
  
  <p>I'm aware of the Pub-Sub Synchronization pattern as described here, <a href="http://zguide.zeromq.org/page:all#Node-Coordination" rel="nofollow">http://zguide.zeromq.org/page:all#Node-Coordination</a>, but NORM, as implemented in the ZeroMQ's norm_engine.cpp (<a href="https://github.com/zeromq/libzmq/blob/master/src/norm_engine.cpp" rel="nofollow">https://github.com/zeromq/libzmq/blob/master/src/norm_engine.cpp</a>) doesn't look like it's set up to allow this pattern. </p>
  
  <p>Is there a way to re-send lost packets, or ensure a healthy multicast connection?</p>
  
  <p>Code is Python.</p>
  
  <p>Publisher:</p>
  
  <pre><code>import zmq
  import time
  import os
  context = zmq.Context()
  socket = context.socket(zmq.PUB)
  socket.connect("norm://224.0.0.1:3000")
  i = 1
  
  imgfile_path = "/home/adam/programs/zmq/tux.svg.png"
  imgsize = os.stat(imgfile_path).st_size
  print "attempting to send", imgsize, "bytes"
  
  sleep_time = 1
  topic = ""
  packet_size = 500
  left = packet_size
  f = open(imgfile_path, 'rb')
  fi = f.read(packet_size)
  while (imgsize - left) &gt; packet_size:
      print "sent packet number:", i
      print "size: ", len(topic + str(i)[-1] + fi)
      i += 1
      socket.send(topic + str(i)[-1] + fi)
  
      fi = f.read(packet_size)
      left += packet_size
      time.sleep(sleep_time)
  print imgsize, left
  time.sleep(sleep_time)
  fi = f.read(imgsize - left)
  print fi
  socket.send(topic + " " + fi)
  f.close()
  </code></pre>
  
  <p>Subscriber:</p>
  
  <pre><code>import zmq
  context = zmq.Context()
  socket = context.socket(zmq.SUB)
  socket.bind("norm://224.0.0.2:3000")
  socket.setsockopt(zmq.SUBSCRIBE, "")
  
  imgdir = "/home/adam/programs/zmq/img/"
  filename = "tux.svg.png"
  destfile = imgdir + filename
  packet_size = 501
  print "attempting to receive"
  f = open(destfile, 'wb')
  while True:
      msg = None
      while msg is None:
          try:
              msg = socket.recv(zmq.NOBLOCK)
          except:
              pass
      if msg: 
          print "msg = ", msg[0]
          print "we got something", len(msg)
          f.write(msg[1:])
          if len(msg) &lt; packet_size:
              break
  f.close()
  print "exiting..."
  </code></pre>
  
  <p>Furthermore, once I can ensure that I can send a file, I'd like to adjust the Forward Error Correction and NACK rate, which is why NORM is so useful to me. Is there a way to do this without re-writing norm_engine.cpp?</p>
  
  <p>Thanks!</p>