помощью класса QUdpSocket. Схема подключения у обоих приложениях одинаковая (подключаюсь к 127.0.0.1 и порт 3000):
socket = new QUdpSocket(this);
if(socket->state() == QAbstractSocket::BoundState)
socket->leaveMulticastGroup(QHostAddress(host));
socket->close();
socket->setSocketOption(QAbstractSocket::KeepAliveOption, QVariant(1));
socket->setSocketOption(QAbstractSocket::MulticastLoopbackOption, QVariant(1));
socket->setSocketOption(QAbstractSocket::MulticastTtlOption, QVariant(255));
bool error = socket->bind(QHostAddress(host), port,
QAbstractSocket::ShareAddress | QAbstractSocket::ReuseAddressHint);
if(!error){
qWarning() << "Bind " << host << port << " failed";
return;
}
if(socket->state() == QAbstractSocket::BoundState)
socket->joinMulticastGroup(QHostAddress(host));
}
Передаю/принимаю дейтаграммы. Принимаю через слот, подключенный к сигналу readyRead().
Запускаю оба приложения, начинаю передачу/прием. Wireshark показывает, что данные отправляются. Принимающее приложение этих данных в упор не видит
Если тот же порядок действий не разносить на два приложения, а делать всё в одном, то всё работает, и прием идет, и передача
Собственно, то приложение (первое), которое принимает - основное, проверял отработку некоторой функции, которая должна анализировать определенным образом входные данные и делать действия. Приложение-передатчик (второе) - тестовое приложение, по-быстрому собранное для локальной проверки, ибо первое приложение извне никаких данных не хочет принимать, только внутри приложения работает прием
Вопрос такой: может, есть какие-то нетривиальные настройки/ограничения, которые я не учел?
Добавьте таймер и по нему принудительно обрабатывайте очередь... в 5.х без такого костыля не работает class TMCastReceiver: public QObject { ... private: QWidget *m_parent; QUdpSocket *saMC; QString receivedData; QMap<QString, QString> recBuffer; QTimer *timer; bool IsReceiveStarted; bool IsReceiveProcess; ... private slots: void processPendingDatagrams(); void timerProcess(); ... } TMCastReceiver::TMCastReceiver(QWidget *parent) :QObject(parent), m_parent(parent), saMC(nullptr) { __DEBUG_MESSAGE; timer = new QTimer(this); IsReceiveStarted = false; IsReceiveProcess = false; connect(timer, SIGNAL(timeout()), this, SLOT(timerProcess())); timer->start( 250); } .... void TMCastReceiver::timerProcess() { if (saMC && IsReceiveStarted && !IsReceiveProcess) processPendingDatagrams(); } ... void TMCastReceiver::processPendingDatagrams() { __DEBUG_ENTER_FUNC__ IsReceiveProcess = true; QString mes; bool is_received = false; while ( saMC->pendingDatagramSize()!=-1 ) { __DEBUG_MESSAGE << "saMC->pendingDatagramSize()=" << saMC->pendingDatagramSize(); QNetworkDatagram dgram = saMC->receiveDatagram(); __DEBUG_MESSAGE << tr("\nReceived IP datagram from %2:%3: \"%1\"") .arg(dgram.data().constData(), dgram.senderAddress().toString()) .arg(dgram.senderPort()); recBuffer[QString("%1:%2").arg(dgram.senderAddress().toString()).arg(dgram.senderPort())] += dgram.data().constData(); is_received = true; } if (!is_received) { __DEBUG_EXIT_FUNC__ IsReceiveProcess = false; return; } receivedData.clear(); ... // разбор ... IsReceiveProcess = false; __DEBUG_EXIT_FUNC__ }
Обсуждают сегодня