使用ZEROMQ和NORM将数据包组播到大量WiFI设备

时间:2015-03-17 18:47:44

标签: sockets python-2.7 network-programming zeromq network-protocols

我正在尝试使用ZeroMQ和NORM协议通过无线网络发送文件。我目前正在使用PUB / SUB模式,因为据我所知,这是NORM与ZeroMQ支持的唯一模式。

我已经设置好了,所以小的消息传递得很好,但偶尔接收器不会收到消息。从那时起,消息就被删除了。这有时可以通过重新启动发布服务器或订阅服务器来解决,但不是每次都重新启动。我已经尝试调整发送的比特数和每次发送呼叫之间的时间无效。在连接变得不稳定之前,我看起来可以收到大约20-60个多播消息。如果我使用相同的代码,但使用TCP进行设置,则连接更加可靠,在发生错误之前会有数千条消息。

我已经尝试实现一个包装器类,在一段时间不活动后重新启动订阅者 - 这不起作用。也没有在while循环中设置socket.recv(zmq.NOBLOCK)。

我知道这里描述的Pub-Sub同步模式http://zguide.zeromq.org/page:all#Node-Coordination,但是在ZeroMQ的norm_engine.cpp(https://github.com/zeromq/libzmq/blob/master/src/norm_engine.cpp)中实现的NORM看起来并不像它的设置允许这种模式。

有没有办法重新发送丢失的数据包,或确保健康的多播连接?

代码是Python。

出版商:

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) > 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()

订户:

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) < packet_size:
            break
f.close()
print "exiting..."

此外,一旦我能确保我可以发送文件,我想调整前向纠错和NACK率,这就是NORM对我这么有用的原因。有没有办法在不重写norm_engine.cpp的情况下做到这一点?

谢谢!

1 个答案:

答案 0 :(得分:1)

您正在假设的部分内容已在文档页面here上得到确认。也就是说,暂时只有PUB / SUB,尽管你可以通过使用NORM for PUB / SUB和TCP for REQ / REP进行链接同步。

否则,我相信你在NORM实施阶段仍处于相当早的阶段,因为(也来自我的链接)它讨论了尚未完成的所有事情。这是从一年前开始的,但从那时起我就没有多少人谈论它。

根据您的基础设施的具体情况,多播甚至可能不是最佳选择,如here所述,没有一种多播协议真正针对当今的高性能网络速度而设计。可能是您的实施正在成为这些传输协议自然结果导致的问题恢复不良的牺牲品。

编辑:

根据您帖子中的github链接,代码自2014年3月19日以来未更新,与我上面链接的页面发布的日期相同,因此关于ZMQ中NORM传输的任何内容都应完全更新-to-日期。

在页面底部,关于ZMQ NORM实现可以做什么和不能做什么的要点:

  1. 当前的“norm_engine”假定了一种相当特殊的NORM传输选项。可能需要通过ZeroMQ API公开其他NORM功能和传输模式。一些例子包括:
    • NORM能够为应用程序提供类似UDP的“尽力而为”和“比尽力而为”(使用数据包擦除编码)传送服务。这将包括控制NORM FEC编码参数。
  2. 因此,看起来它(在当前状态下)无法控制前向纠错,只需在默认的反应(高性能)状态下使用它。默认情况下,此 应为提供连接的可靠性,但如果ZMQ实施尚未彻底完成,则可能比您想要的更脆弱。由于缺乏内容和补丁,我认为它还没有为你做好准备。