【问题标题】:QUdpSocket - datagram is being received twice, why?QUdpSocket - 数据报被接收两次,为什么?
【发布时间】:2018-11-01 18:02:14
【问题描述】:

我在我的 QUdpSocket 上收到了两次数据报,即使我正在使用 wireshark 并且只收到一次。我创建套接字并在端口 11112 上侦听。还有另一个设备在我正在侦听的此端口上发出数据。对于发送的每条实际消息,我始终收到两条消息。我不确定是什么原因造成的。有什么想法吗?

精简代码:

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_socket = new QUdpSocket(this);
          connect (m_socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
          m_socket->bind(11112, QUdpSocket::ShareAddress);
}

MainWindow::~MainWindow()
{
    delete ui;
    delete m_socket;
}

void MainWindow::readPendingDatagrams()
{
    QByteArray buffer;
    QHostAddress sender;
    quint16 port;

    while(m_socket->hasPendingDatagrams())
    {
        int s = m_socket->pendingDatagramSize();
        buffer.resize(s);
        //for some reason there are two datagrams on the line.
        // I have verified with wireshark that there is only one from the
        // sender so not sure what is happening under the hood...
        m_socket->readDatagram(buffer.data(),buffer.size(),&sender, &port);

        QString source = sender.toString().split(":")[3];
        if (source == "172.20.23.86")
        {
            qInfo() << buffer <<endl;
        }
    }


}

void MainWindow::onSocketStateChange(QAbstractSocket::SocketState state)
{
    if ( state == QAbstractSocket::BoundState ) {
           connect(m_socket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
       }

}

【问题讨论】:

    标签: c++ qt qt5 qudpsocket


    【解决方案1】:

    如果数据报被发送到广播地址,并且您绑定到所有接口(0.0.0.0),并且有两个接口接收数据报,则可能会发生这种情况。要排除这种可能性,请切换到 receiveDatagram API 并转储您收到的数据报的全部详细信息。我敢打赌,您收到它的界面每次都会有所不同。

    您还可能多次连接readPendingDatagrams 插槽,因此它可能会被多次触发,尽管hasPendingDatagrams 应该第二次返回false - 所以虽然这可能不是 问题,这是您必须解决的 问题。它应该只连接一次 - 当您构造套接字时,即在构造函数中。

    【讨论】:

    • 你能解释一下我是如何多次连接 readPendingDatagrams 的吗?
    • 我按照建议更改了代码,但行为没有改变
    • @CarlBartlett 您连接了多次,因为每次套接字绑定时您都连接了。这可能会在应用程序生命周期内多次发生,并且无论如何都是不必要的复杂化:以后再连接到信号是没有意义的。
    • 我用断点验证,socket只绑定一次,虽然原则上我同意,不是连接多次。
    • socket可以绑定一次,但是可以绑定多个接口...
    【解决方案2】:

    Unslander Monica 是正确的,它默认绑定到所有接口,您可以通过 m_socket->bind(QHostAddress::LocalHost,11112); 修复它

    【讨论】:

      猜你喜欢
      • 2012-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-20
      • 1970-01-01
      相关资源
      最近更新 更多