Qt程序仅从某些IP地址接收UDP

时间:2014-07-02 10:39:18

标签: linux qt sockets embedded freertos

当STM32设置为某些看似随机但特定的IP地址时,我的Qt程序只接收来自STM32模块的UDP [Artnet]数据报。

所以,我有以下内容:

  1. Linux Machine运行带有动态IP地址的Qt程序
  2. STM32运行FreeRTOS模块手动设置为地址A
  3. STM32运行FreeRTOS模块手动设置为地址B
  4. 我已经编写了Qt软件并在STM32板上使用uIP和FreeRTOS - 修改uIP以正确使用UDP并添加简单的Artnet代码。

    所有都在192.168.0.x子网上。

    我已经编写了Qt程序,将Artnet民意调查发送到子网的广播地址。因此,它将UDP端口6454上的标准Artnet轮询发送到地址192.168.0.255。 Wireshark,显示我的两个STM32模块返回Artnet民意调查回复就好了。到现在为止还挺好。

    然而,如果我开始变得非常奇怪的是,例如,如果我将一个STM32设置为IP地址为192.168.0.177而另一个设置为192.168.0.176,那么177节点将被Qt看到并处理但是,尽管176节点发回了正确的Artnet民意调查回复,但Qt程序却断然拒绝阅读回复数据包。如果我将176节点的IP地址更改为.44,则Qt程序将处理该答复。如果我将[工作] .177节点更改为,例如.43,则它不起作用。

    我应该强调的是,无论我将STM32设置为什么IP地址,Wireshark都会表示答复一切顺利。

    有人可以提出任何可能会对此有所了解吗?我曾经玩过netcat,但这似乎无法阅读任何这些Artnet回复,无论它们来自哪个地址,所以我可能会误解netcat可以做什么。我用我的Qt程序尝试netcat只有开放和出站端口,而不是入站,它没有任何区别,但同样,我可能会完全误解netcat或UDP的东西。也许如果你打开一个出站UDP端口,会自动打开相同的入站?

    在我的Linux机器上没有发生IP地址冲突,我没有打开防火墙。

    非常感谢。

    编辑:根据要求添加了代码。

    void MainWindow::processPendingDatagrams(void)
    {
        struct ArtNetPollReplyStruct *newReply;
        QHostAddress sendingAddress;
        quint16 sendingUdpPort;
        QString versionString;
        QByteArray datagram;
    
        while (udpReceiveSocket->hasPendingDatagrams())
        {       
            datagram.resize(udpReceiveSocket->pendingDatagramSize());
            udpReceiveSocket->readDatagram(datagram.data(), datagram.size(), &sendingAddress,&sendingUdpPort);
            newReply = (struct ArtNetPollReplyStruct*)(datagram.data());
            if (newReply->OpCode == OP_POLL_REPLY)
                {
                if (sendingAddress != QHostAddress("192.168.0.18"))
                    {
                    if (checkAndAddAddress(sendingAddress))
                        {
                        versionString = QString::number(newReply->VersionInfoH,10) + "." + QString::number(newReply->VersionInfo,10);
                        addNodeToList(sendingAddress.toString(), versionString);
                        ui->textEdit->append( QString::fromUtf8(newReply->LongName));
                        }
                    }
                }
            }
    }
    

    初始化UDP端口的代码如下:

    udpSendSocket = new QUdpSocket(this); udpReceiveSocket = new QUdpSocket(this);    
    udpSendSocket->bind(6454, QUdpSocket::ShareAddress); 
    udpReceiveSocket->bind(QHostAddress::Any,6454);
    connect(udpReceiveSocket, SIGNAL(readyRead()),this, SLOT(processPendingDatagrams()));
    connect(ui->innoLEDListTable,SIGNAL(itemChanged(QTableWidgetItem*)),this,SLOT(tableItemClicked(QTableWidgetItem*)));
    
    $ ifconfig
    enp5s0    Link encap:Ethernet  HWaddr 14:DA:E9:30:36:22  
              inet addr:192.168.0.18  Bcast:192.168.0.255  Mask:255.255.255.0
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:265615 errors:0 dropped:0 overruns:0 frame:0
              TX packets:190104 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000 
              RX bytes:306893983 (292.6 MiB)  TX bytes:20997451 (20.0 MiB)
    
    lo        Link encap:Local Loopback  
              inet addr:127.0.0.1  Mask:255.0.0.0
              UP LOOPBACK RUNNING  MTU:65536  Metric:1
              RX packets:25205 errors:0 dropped:0 overruns:0 frame:0
              TX packets:25205 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0 
              RX bytes:6063842 (5.7 MiB)  TX bytes:6063842 (5.7 MiB)
    
    $ route -n
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         192.168.0.2     0.0.0.0         UG    10     0        0 enp5s0
    169.254.0.0     0.0.0.0         255.255.0.0     U     10     0        0 enp5s0
    192.168.0.0     0.0.0.0         255.255.255.0   U     10     0        0 enp5s0
    

1 个答案:

答案 0 :(得分:2)

你只需要一个插座。你的问题是数据报到达你从未读过的另一个套接字。套接字是双向的。