Qt5: connectToHost() 接收广播udp数据报
Qt5: connectToHost() to receive broadcast udp datagram
我可以使用 QAbstractSocket::connectToHost() 来接收广播 udp 数据报吗?
如果我尝试未修改的 broadcastsender/receiver 一切正常,netstat 是:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp6 0 0 :::52337 :::* 12185/./broadcastse
udp6 0 0 :::45454 :::* 12172/broadcastrece
我修改了broadcastreceiver如下:
//! [0]
udpSocket = new QUdpSocket(this);
udpSocket->bind(45454, QUdpSocket::ShareAddress);
udpSocket->connectToHost(QHostAddress(QHostAddress::Any),0); // <- added line
//! [0]
现在它不接收广播数据报,但它能正确接收单播数据报。
netstat 命令报告为:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp6 0 0 ::1:45454 ::1:* ESTABLISHED 11488/broadcastrece
我想知道为什么本地地址看起来不同,我哪里错了。
此致
最大值
如果您查看 official documentation of QUdpSocket,您将看到以下段落,它很好地解释了如何使用 QUdpSocket:
The most common way to use this class is to bind to an address and
port using bind()
, then call writeDatagram()
and readDatagram()
/
receiveDatagram()
to transfer data. If you want to use the standard
QIODevice
functions read()
, readLine()
, write()
, etc., you must first
connect the socket directly to a peer by calling connectToHost()
.
所以你对 connectToHost()
的调用是 没有必要,你应该改为只绑定然后监听信号 readyRead()
并从插槽中使用readDatagram()
获取原始数据包数据或 receiveDatagram()
获取预解析数据。
这似乎违反直觉,但由于 UDP 协议的性质,没有连接,任何节点都可以向任何其他未发起的节点发送数据包,所以一旦你 bind()
你可以收到来自任何人的 UDP 数据包。
在这种情况下,源地址和端口将成为数据报本身的一部分。您可以在 receiveDatagram()
函数签名的参数中看到这一点:
qint64 QUdpSocket::readDatagram(char *data, qint64 maxSize, QHostAddress *address = Q_NULLPTR, quint16 *port = Q_NULLPTR)
请注意,您可能会遇到通过 UDP 进行通信的问题,因为任何转换网关(NAT 路由器)都会丢弃所有未启动的数据包。这是一个常见问题,除非您控制端点之间的路由器,否则需要一些 clever tricks 才能绕过。
希望这对您有所帮助。
我可以使用 QAbstractSocket::connectToHost() 来接收广播 udp 数据报吗?
如果我尝试未修改的 broadcastsender/receiver 一切正常,netstat 是:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp6 0 0 :::52337 :::* 12185/./broadcastse
udp6 0 0 :::45454 :::* 12172/broadcastrece
我修改了broadcastreceiver如下:
//! [0]
udpSocket = new QUdpSocket(this);
udpSocket->bind(45454, QUdpSocket::ShareAddress);
udpSocket->connectToHost(QHostAddress(QHostAddress::Any),0); // <- added line
//! [0]
现在它不接收广播数据报,但它能正确接收单播数据报。
netstat 命令报告为:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp6 0 0 ::1:45454 ::1:* ESTABLISHED 11488/broadcastrece
我想知道为什么本地地址看起来不同,我哪里错了。
此致 最大值
如果您查看 official documentation of QUdpSocket,您将看到以下段落,它很好地解释了如何使用 QUdpSocket:
The most common way to use this class is to bind to an address and port using
bind()
, then callwriteDatagram()
andreadDatagram()
/receiveDatagram()
to transfer data. If you want to use the standardQIODevice
functionsread()
,readLine()
,write()
, etc., you must first connect the socket directly to a peer by callingconnectToHost()
.
所以你对 connectToHost()
的调用是 没有必要,你应该改为只绑定然后监听信号 readyRead()
并从插槽中使用readDatagram()
获取原始数据包数据或 receiveDatagram()
获取预解析数据。
这似乎违反直觉,但由于 UDP 协议的性质,没有连接,任何节点都可以向任何其他未发起的节点发送数据包,所以一旦你 bind()
你可以收到来自任何人的 UDP 数据包。
在这种情况下,源地址和端口将成为数据报本身的一部分。您可以在 receiveDatagram()
函数签名的参数中看到这一点:
qint64 QUdpSocket::readDatagram(char *data, qint64 maxSize, QHostAddress *address = Q_NULLPTR, quint16 *port = Q_NULLPTR)
请注意,您可能会遇到通过 UDP 进行通信的问题,因为任何转换网关(NAT 路由器)都会丢弃所有未启动的数据包。这是一个常见问题,除非您控制端点之间的路由器,否则需要一些 clever tricks 才能绕过。
希望这对您有所帮助。