1

我有一组虚拟设备 (D)。设备可以交叉连接(假设,物理连接):

D1——D2

D2——D3

每个链接可能会有不同的延迟。

每个设备都包含一组可以生成一些数据的虚拟子设备。子设备可以组织成逻辑连接。子设备将传输真实的字节数据。

我使用 C++,Qt。我尝试使用信号槽机制,QSignalMapper,但我没有找到好的解决方案。

请帮助我建立清晰的抽象。我可以使用任何设计模式吗?

4

1 回答 1

1

您应该定义一个Link类来模拟类之间的物理链接。最有趣的问题是,如何连接您的设备并使用信号和插槽模拟延迟?

我的建议是:实现一个send(QByteArray data)插槽,将数据排入内部队列(模拟线路),并将超时设置为给定的默认延迟,并带有可选的抖动。然后超时会触发一个信号,其中包含从队列中弹出的数据。

如果你想模拟设备之间的路由器,你应该考虑到队列中的数据越多,延迟就越大,因为需要重新传输。为了近似模拟这一点,您可以根据当前队列长度设置超时值。

以此为开端:

class Link : public QObject
{
    Q_OBJECT

public:
    Link(Device *from, Device *to) :
        QObject(to), m_from(from), m_to(to)
    {
        //make my life dependant on both "from" and "to" objects
        connect(from, SIGNAL(destroyed()), SLOT(deleteLater()));

        //connect to the signals and slots of the devices
        connect(from, SIGNAL(send(QByteArray,Device*)),
                this, SLOT(  send(QByteArray,Device*)));
        connect(this, SIGNAL(receive(QByteArray,Device*,int)),
                to,   SLOT(  receive(QByteArray,Device*,int)));
    }

public slots:
    void send(QByteArray data, Device *receiver) {
        Message msg(data, 0, qobject_cast<Device*>(sender()), receiver);
        send(msg);
    }
    void send(Message msg) {
        msg.hops++; // here we increase the hops counter
        m_queue.enqueue(msg);
        QTimer::signalShot(m_delay, this, SLOT(timeout()));
    }

signals:
    void receive(QByteArray data, Device *sender, int hops);
    void forward(Message);

private slots:
    void timeout() {
        receive(m_queue.dequeue());
    }
    void receive(Message msg) {
        if(msg.receiver == m_to)
            // msg reached destination!
            emit receive(msg.data, msg.sender, msg.hops);
        else
            // forward to next link
            emit forward(msg);
    }

private:
    static const int m_delay = 100; // delay set to 100 ms
    QQueue<Message> m_queue;
    Device *m_from, *m_to;
};

类型Message定义如下:

struct Message {
    QByteArray data;
    int hops;
    Device *sender;
    Device *receiver;
    Message(data, hops, sender) : data(data), hops(hops),
                                  sender(sender), receiver(receiver) {}
};

然后像这样创建设备和链接:

// Create devices:
Device *d1 = new Device(this);
Device *d2 = new Device(this);

// Create link:
Link *d1d2 = new Link(d1, d2);

或带有转发规则的链接:

// Create devices:
Device *d1 = new Device(this);
Device *d2 = new Device(this);
Device *d3 = new Device(this);

// Create links:
Link *l1 = new Link(d1, d2);
Link *l2 = new Link(d2, d3);

// Create forwarding rule:
connect(l1, SIGNAL(forward(Message)), l2, SLOT(send(Message)));

然后d1 发送的每个数据(当它发出信号时send(QByteArray))将延迟 100 ms 传输到receive(QByteArray)d2 的插槽。如果数据不是用于 d2,则forward(Message)发出信号,该信号必须被另一个链接捕获(请参阅转发规则)。然后它被视为新的传入消息并传递给 d3。

请注意,真实网络的功能并非如此。您需要实施路由策略来完全模拟这样的设置;这是相当困难的。

另请注意,我没有测试此代码。;)

这种方法不会模拟将数据分成小段(每个大约 1.5 KB)。要模拟真实的以太网设置,您也需要这样做。如果您需要,请在评论中询问,我可能会扩展课程。

于 2012-05-22T11:23:58.073 回答