2014-07-02 45 views
2

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

所以,我有以下几点:

  1. 的Linux机器上运行与动态IP地址的Qt程序
  2. STM32运行FreeRTOS的模块手动设置来解决一个
  3. STM32运行FreeRTOS的模块手动设置为地址B

我已经编写了Qt软件,并在STM32板上使用了带有FreeRTOS的uIP - 修改了uIP以正确使用UDP并添加了简单的Artnet代码。

全部位于192.168.0.x子网上。

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

然而,它开始变得非常奇怪的是,例如,如果我设置一个STM32的IP地址为192.168.0.177,另一个为192.168.0.176,那么177节点就会被Qt程序,尽管176节点发回一个正确的Artnet轮询答复,但Qt程序坚决拒绝读取答复数据包。如果我将176节点的IP地址更改为.44,那么Qt程序将处理该答复。如果我将[working] .177节点更改为.43,则不起作用。

我应该强调,无论我设置STM32的IP地址为何,Wireshark都表示所有回复都正常。

任何人都可以提出任何可能阐明这一点吗?我玩过netcat,但似乎没有读到任何这些Artnet的回复,不管他们来自哪个地址,所以我可能会误解netcat的功能。我已经尝试过使用我的Qt程序netcat只打开和出站端口,而不是入站,并没有什么区别,但是,我可能完全误解了netcat或UDP的一些东西。也许如果你打开一个出站UDP端口,相同的入站会自动打开?

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

非常感谢。

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

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 
+0

如果不显示读取数据包的源代码,此问题无法解析。请举一个最简单的例子:从一个空的'main.cpp'文件开始,只添加设置套接字所需的最少代码,并将一个数据包放入'QByteArray'中。在这一点上,问题应该表现出来,我希望。 –

+0

也请在linux机器上显示'ifconfig'和'route -n'输出。 –

+0

我已经按要求添加了信息。当IP地址更改为.176时,processPendingDatagrams()函数根本不会被调用,所以我不认为这是Qt代码的那部分问题。虽然我很高兴被证明是错误的!非常感谢:) – DiBosco

回答

2

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

+0

哇,你说得对。 Qt邮件列表中没有任何人可以看到这一点,很棒的地方。这是我第一次使用UDP/IP,更不用说Qt了。太感谢了。 – DiBosco

+0

@DiBosco这不是Qt特有的。如果你直接使用POSIX/Unix API,它会是一样的。唉,我只是接受它,因为我让你发布*相关*代码。我不知道邮件列表中的任何人是否看到了该代码。因此,几乎总是这样,问题提出者不断发布自己的脚印,没有发布完整,可编译,最小化的例子来证明他们的困境。看看我的答案。我发布了超过一百个Qt答案,其中包含自包含的单个文件示例。有一些比较复杂:) –

+0

@DiBosco问题的一部分是欺骗性的变量命名:'udpSendSocket'不仅仅是发送套接字。一个有用的调试技巧是想象你的所有变量都有无意义的名字:) –