2014-07-02 40 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'不僅僅是發送套接字。一個有用的調試技巧是想象你的所有變量都有無意義的名字:) –