代码之家  ›  专栏  ›  技术社区  ›  paxdiablo

Qt 5.5未绑定到端口

  •  0
  • paxdiablo  · 技术社区  · 7 年前

    它基本上是联系echo服务器来检测设备是否在网络上,首先设置UDP发送方和接收方,然后发送数据包并检查其是否返回。

    问题在于绑定接收套接字:

    // Create the two sockets.
    
    m_sendSocket = new QUdpSocket(this);
    m_recvSocket = new QUdpSocket(this);
    
    // Connect sending socket to other end.
    
    m_sendSocket->connectToHost(QHostAddress(host), 43837);
    
    // Bind receiving socket so it will receive any response.
    
    bool x = m_recvSocket->bind(m_sendSocket->localPort());
    std::cout << x << " " << m_sendSocket->localPort() << std::endl;
    

    它创建两个套接字(传出和传入),然后尝试将传出套接字的本地端口绑定到传入套接字的接收端口(以便可以拾取响应)。

    这在Windows环境下运行良好,但 bind 在Linux下失败。因为它返回的都是布尔值,所以我不知道 它失败了。

    考虑到这可能是平台的默认绑定模式,我还尝试显式设置,以便Linux与Windows匹配:

    bool x = m_recvSocket->bind(m_sendSocket->localPort(), QAbstractSocket::ShareAddress);
    

    但这没有帮助。

    发送方套接字的本地端口似乎没有问题,我看到了如下值 38349 , 58597 37433 .

    有人知道这可能失败的原因吗,或者Qt是否在某些地方提供了更多关于 为什么?

    1 回复  |  直到 7 年前
        1
  •  0
  •   paxdiablo    7 年前

    m_recvSocket->errorString() . 在您的情况下,修改 cout 线路为:

    std::cout << x
        << " " << m_sendSocket->localPort()
        << " " << m_recvSocket->errorString().toStdString()
        << std::endl;
    

    你会看到类似“地址已在使用”的东西,因为正如你所意识到的,Windows和Linux有不同的默认绑定模式——前者是一个更共享的操作系统,而后者似乎是报复性和占有性的 .

    所以 正在发送 connectToHost() ,这意味着接收套接字无法绑定到它。

    解决这个问题的方法是在连接到主机之前,将发送套接字显式绑定到共享选项。这可以通过以下方式实现:

    m_sendSocket = new QUdpSocket(this);
    m_recvSocket = new QUdpSocket(this);
    m_sendSocket->bind(0, QAbstractSocket::ShareAddress);
    m_sendSocket->connectToHost(QHostAddress(host), 43837);
    bool x = m_recvSocket->bind(m_sendSocket->localPort(), QAbstractSocket::ShareAddress);
    std::cout << x
        << " " << m_sendSocket->localPort()
        << " " << m_recvSocket->errorString().toStdString()
        << std::endl;
    

    结果是:

    1 47334 Unknown error
    

    在我的系统上,由于返回值为 bind 1 在输出线上)。


    (a) Pax鸭子作掩护:-)