Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 数据交换的设计模式_C++_Oop_Qt_Design Patterns_Signals Slots - Fatal编程技术网

C++ 数据交换的设计模式

C++ 数据交换的设计模式,c++,oop,qt,design-patterns,signals-slots,C++,Oop,Qt,Design Patterns,Signals Slots,我有一组虚拟设备(D)。 设备可以交叉连接(假设为物理连接): D1--D2 D2--D3 每个链接可能会有不同的延迟 每个设备都包含一组可以生成某些数据的虚拟子设备。 子设备可以组织为逻辑连接。 子设备将传输实字节数据 我使用C++,Qt。 我尝试使用信号槽机制QSignalMapper,但没有找到好的解决方案 请帮我建立清晰的抽象概念。 我可以使用任何设计模式吗?您应该定义一个链接类来模拟类之间的物理链接。最有趣的问题是,如何连接设备并使用信号和插槽模拟延迟 我的建议是:实现一个send(Q

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

D1--D2

D2--D3

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

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

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

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

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

我的建议是:实现一个
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;
};
然后只需创建如下设备和链接:

// 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发送的每个数据(当其发出信号时)将以100毫秒的延迟传输到d2的插槽
接收(QByteArray)
。如果数据不是针对d2的,则会发出信号
转发(消息)
,该信号必须被另一个链接捕获(请参阅转发规则)。然后,它被视为一条新的传入消息,并被传递到d3

请注意,真正的网络不是这样工作的。您需要实施路由策略来完全模拟这样的设置;这是相当困难的

还要注意,我没有测试这段代码。;)


这种方法不模拟将数据分割成小片段(每个片段大约1.5 KB)。要模拟真实的以太网设置,您也需要这样做。如果需要,请输入注释,我可以扩展该类。

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

我的建议是:实现一个
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;
};
然后只需创建如下设备和链接:

// 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发送的每个数据(当其发出信号时)将以100毫秒的延迟传输到d2的插槽
接收(QByteArray)
。如果数据不是针对d2的,则会发出信号
转发(消息)
,该信号必须被另一个链接捕获(请参阅转发规则)。然后,它被视为一条新的传入消息,并被传递到d3

请注意,真正的网络不是这样工作的。您需要实施路由策略来完全模拟这样的设置;这是相当困难的

还要注意,我没有测试这段代码。;)


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

您有物理连接且有延迟的虚拟设备吗?您是在模拟网络还是那些设备?不清楚您在虚拟设备之间寻找的是哪种类型的
连接
链接。他们只是需要能够互相调用方法吗?此外,子设备扮演什么角色?好的,首先让设备(D)是子设备的容器(组)。也许将来我会为设备(组)添加特殊属性。最有趣的问题是:如何在OOP中描述链接?它可以将数据传输到设备,可以延迟,等等。我如何链接数据和设备类?您可以有一个连接类,使用两个QIODevice并将数据从一个QIODevice铲到另一个。@Frankosterfield谢谢!我应该从QIODevice基类继承我的设备类。你有物理连接的虚拟设备并且有延迟吗?您是在模拟网络还是那些设备?不清楚您在虚拟设备之间寻找的是哪种类型的
连接
链接。他们只是需要能够互相调用方法吗?此外,子设备扮演什么角色?好的,首先让设备(D)是子设备的容器(组)。也许将来我会为设备(组)添加特殊属性。最有趣的问题是:如何在OOP中描述链接?它可以将数据传输到设备,可以延迟,等等。我如何链接数据和设备类?您可以有一个连接类,使用两个QIODevice并将数据从一个QIODevice铲到另一个。@Frankosterfield谢谢!当然,我应该从QIODevice基类继承我的设备类。很好,这是一个很好的起点。你的链接类非常清晰。但是如果我有一个设备树,我能把Link连接到c吗