【问题标题】:QUdpSocket not working without bindQUdpSocket 在没有绑定的情况下无法工作
【发布时间】:2017-09-13 13:11:48
【问题描述】:

我必须通过 UDP 与某些设备通信。问题是如果没有bind() 的特殊情况,QUdpSocket 根本不起作用。我使用connectToHost()方法for access to read()/write() functions

使用代码时UDP交换根本不起作用:

m_udp.connectToHost(QHostAddress("192.168.100.15"), 4001);    
m_udp.waitForConnected();

我没有收到任何字节。 Wireshark 中的消息:

下面的代码也不起作用:

m_udp.bind(QHostAddress("192.168.100.15"), 4001);
m_udp.connectToHost(QHostAddress("192.168.100.15"), 4001);    
m_udp.waitForConnected();

只有这段代码有效:

m_udp.bind(4001);
m_udp.connectToHost(QHostAddress("192.168.100.15"), 4001);    
m_udp.waitForConnected();

但该代码仅适用于 Qt 5.6.2,不适用于 Qt 5.4.2。 以下是我尝试接收的方式:

dev->waitForReadyRead(500);
QByteArray ba = dev->readAll();

为什么行为如此奇怪?这怎么能理解?

【问题讨论】:

    标签: qt network-programming udp qt5 qudpsocket


    【解决方案1】:

    您还没有显示另一端的代码,但显然从显示的wireshark图像中,远程对等方期望您的套接字绑定到端口4001。

    第一个代码 sn -p 尝试在不指定本地端口的情况下连接到 (RemoteAddress, 4001)(因此内核分配了一个任意端口号(根据 wireshark 为 64875)但如上所述,另一端是 期望发送回端口 4001。因此您无法在端口 64875 上接收它。

    在 UDP 中,没有实际连接之类的东西。当您使用connectToHost 时,您实际上只是指定了远程端的IP 地址和端口号。确保远程端发送回正确的端口是应用程序的责任。这可以通过 (a) 始终发送到特定端口来完成(正如这里显然所做的那样),或者 (b) 另一方可以查看实际接收数据报的地址/端口并将其发送回该地址/端口;换句话说,远程端可以确定它收到的数据报是从端口 64875 发送的,并将其回复定位到该端口。

    在第二次尝试中,您尝试将本地端点绑定到另一台机器上的地址,这根本没有任何意义。 (我猜如果你将绑定更改为m_udp.bind(QHostAddress("192.168.100.3"), 4001);——你的本地机器的 IP 地址,这个 sn-p 会起作用。)

    只有第三个 sn-p 有效,因为在这里您绑定到本地端口 4001 而不指定 IP 地址,然后还发送到远程计算机上的端口 4001。如果您仅在 bind 中指定端口号,则 IP 地址将保留为“通配符”,因此您应该将数据包发送到您机器的任何 IP 地址上的该端口号。

    (不知道为什么您会在早期版本的 Qt 中看到不同的行为。)

    【讨论】:

      【解决方案2】:

      在写入或读取之前检查绑定后套接字的状态。

      查看此代码:

      QHostAddress serverIP("172.168.1.100");
      if(socket->bind(serverIP,port,QUdpSocket::ShareAddress)) //even if local Host dont have static IP( on subnet expected 172.168.x.x),still it becomes true and enters if.
          {
          if( (socket->state() == QAbstractSocket::BoundState) && (((socket->localAddress()).protocol()) == QAbstractSocket::IPv4Protocol) ) //ignore protocol validation if not required.
              {
      
               }
       else
              {
                  qDebug()<<"Socket not in bound state. address is: "<<QHostAddress::LocalHost<<" and the port "<<port;
                  //Return = false;
              }
          }
      else
          {
              qDebug()<<"Failed to bind socket to the address "<<QHostAddress::LocalHost<<" and the port "<<port;
              //Return = false;
          }
      

      其次,如果出现问题,Qt 中的套接字会发出错误信号。所以你应该有一个槽来捕捉这些错误信号。这样您就可以知道问题背后的原因。

      例如:

      connect(udpsocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(onSocketError(QAbstractSocket::SocketError)));
      

      接收 socker 错误的槽:

      void SomeInterface::onSocketError(QAbstractSocket::SocketError socketError)
      {
          qDebug()<<"socket error occured and the error is : "<<socketError;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-19
        • 2012-04-01
        • 1970-01-01
        • 2012-12-21
        • 2012-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多