Qt 5.5没有绑定到端口

时间:2017-10-18 02:37:12

标签: linux qt udp bind

我有一些代码在Windows下的Qt 5.9中运行良好但在Linux下导致Qt 5.5出现问题。

它基本上是联系一个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);

但这没有帮助。

发件人套接字的本地端口似乎没问题,我看到383495859737433等值。

有谁知道为什么这可能会失败,或者Qt是否在为什么失败时提供更多信息,或者是否有更好的方法来做到这一点(这不会失败)?

1 个答案:

答案 0 :(得分:0)

您可以通过访问m_recvSocket->errorString()从套接字获取更多信息。在您的情况下,请将cout行修改为:

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

你所看到的是&#34;已经在使用的地址&#34;因为,正如您所知,Windows和Linux具有不同的默认绑定模式 - 前者是更多共享操作系统,而后者似乎是报复性和占有性(a)

因此发送套接字有效地锁定了它在调用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的返回值为true(输出行上的初始1)。

(a) Pax ducks for cover: - )