linux - Qt程序只接收来自特定IP地址的UDP

标签 linux qt sockets embedded freertos

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

所以,我有以下内容:

  1. 使用动态IP地址运行Qt程序的Linux机器
  2. STM32运行FreeRTOS模块手动设置地址A
  3. STM32运行FreeRTOS模块手动设置地址B

我编写了 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,则 Qt 会看到并处理 177 节点程序,然而,尽管 176 节点发回了正确的 Artnet 轮询回复,Qt 程序断然拒绝读取回复数据包。如果我将 176 节点的 IP 地址更改为 .44,则 Qt 程序会处理回复。如果我将 [working] .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

最佳答案

您只需要一个 socket 。您的问题是数据报到达了您从未读取过的另一个套接字。套接字是双向的。

关于linux - Qt程序只接收来自特定IP地址的UDP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24529039/

相关文章:

linux - 升级到压缩/测试期间 Perl 冲突

linux - docker: `top` 和 `ps` 的不同 PID

qt - 如何在 Qt Designer 中编辑后隐藏 Tab 键顺序

sockets - 为什么许多库没有检测到无效的TCP连接?

c - 使用 epoll 在客户端监听不同的多播套接字

javascript - Node.js/Express - 如何通过方法(使用套接字)访问 session 数据?

linux - 我怎么知道是 "init"还是 "systemd"控制着 docker?

linux - 如果没有响应,BASH 会杀死 wget

qt - defaultServiceProvider::requestService(): 找不到服务 - "org.qt-project.qt.camera"

c++ - 从 QStandardItemModel - TableView 获取 QImage 或 QPixmap