【发布时间】:2018-03-08 08:27:54
【问题描述】:
我有一个关于 QUdpSocket 的问题:
我大约每 0.2 秒在端口50011 上接收到多播地址239.0.0.1 的UDP 消息(由wireshark 证明)。
以下代码运行良好(并在每条消息上打印“VALID”)约 1 分钟。之后messageHandler 不再被QUdpSocket's 信号readyRead 调用(即使我已经用wireshark 仔细检查过,消息仍在发送中)。
ServiceDiscovery::ServiceDiscovery(QObject *parent) :
QObject(parent),
socket(new QUdpSocket(this))
{
socket->bind(QHostAddress::AnyIPv4, 50011, QUdpSocket::ShareAddress);
socket->joinMulticastGroup(QHostAddress("239.0.0.1"));
connect(socket, &QUdpSocket::readyRead,
this, &ServiceDiscovery::messageHandler,
Qt::DirectConnection);
}
void ServiceDiscovery::messageHandler()
{
if(socket->isOpen()) qDebug("OPEN"); // Does not print, ofc.
if(socket->isReadable()) qDebug("READABLE"); // Does not print.
if(socket->isValid()) qDebug("VALID"); // Suddenly stops.
QByteArray datagram;
while(socket->hasPendingDatagrams()) {
datagram.resize(socket->pendingDatagramSize());
socket->readDatagram(datagram.data(), datagram.size());
Message response(datagram);
if(response.deserialize()) {
if(response.getServiceID() == constants::servicediscovery::SERVICE_ID) {
QByteArray payload = response.getPayload();
if(payload.size() >= 48) {
QString address = QHostAddress(payload.mid(32, 4).toHex().toUInt(nullptr, 16)).toString();
quint16 port = payload.mid(38, 2).toHex().toUInt(nullptr, 16);
emit found(address, port);
}
}
}
}
}
我在这里做错了什么? 提前致谢。
编辑:由于 cmets,我也粘贴了数据报处理。
【问题讨论】:
-
如果你注释掉处理数据报的代码怎么办?可能是您的系统无法处理这么多请求(每秒至少 5 个),或者死锁。
-
@vahancho 我更新了代码。 'response.deserialize()' 正在从数据报中形成一个 QString。
-
抱歉,“注释掉”是指删除该代码,根本不处理数据报。这将使事情运行得更快。如果它工作得更快,它将处理更多的消息。如果您会看到仍然打印“VALID”消息,这表明您的数据报处理代码无法处理那么多待处理的数据报,而只是阻塞了事件循环。
-
我不能注释掉它,因为我的应用程序依赖于它。但死锁是一个很好的猜测。当存在导致它的性能问题时,简单地让处理程序重新进入并不能解决我的问题......
标签: c++ qt udp signals-slots qudpsocket