Приветствую.
Проблема в следующем- надо запустить в отдельном потоке прослушивание UDP сокета с тайм аутом в n секунд, после чего в основном потоке отправить данные по другому UDP сокету.
Последовательность именно такая, чтобы не пропустить принимаемый пакет. Вопрос, как это сделать?
Вариант с методом класса QAbstractSocket::waitForReadyRead()
отпадает, т.к. он нестабильно работает на Windows. Версия QT 5.8.0.
Примерный псевдокод (Скорее всего, есть средства QT, которые помогут выполнить эти действия куда быстрее и изящнее, но т.к. я новичок в QT, я их не знаю):
QDatagram Функция Прием_Данных
Пока i < Timeout
считать данные с сокета
Если данные есть
вернуть QDatagram
Конец
i+=100;
Остановить процесс на 100 мс
Конец
вернуть QDatagram
Конец
Основная функция
В отдельном потоке запустить Прием_Данных
Отправить данные на устройство
Ожидать выполнение функции Прем_Данных
Конец
Пример слушает UDP порт localhost:50080
, логирует всё, что в него пришло, модифицирует сообщение ставя перед ним Hey, I've received a message:
и отсылает на localhost:50081
. Если нет сообщений в течении 5 секунд — приложение завершается.
#include <QtCore/QCoreApplication>
#include <QtCore/QTime>
#include <QtCore/QTimer>
#include <QtCore/QDebug>
#include <QtCore/QByteArray>
#include <QtNetwork/QUdpSocket>
#include <QtNetwork/QHostAddress>
#include <stdint.h>
class QUdpSocketCat: public QObject {
Q_OBJECT
QUdpSocket *in;
QUdpSocket *out;
QTimer *timer;
public:
explicit QUdpSocketCat(QObject *parent=0):
QObject(parent)
{
in = new QUdpSocket(this);
out = new QUdpSocket(this);
timer = new QTimer(this);
// connection data
in->bind(QHostAddress::LocalHost, 50080);
out->connectToHost(QHostAddress::LocalHost, 50081);
// connect signal on receiving new data
connect (in, SIGNAL(readyRead()), this, SLOT(catData()));
// setup timer
timer->start(5000);
connect (timer, &QTimer::timeout, [] () {
qDebug() << QTime::currentTime().toString()
<< "I'm so lonely... goodbye cruel world...";
QCoreApplication::instance()->exit();
});
qDebug() << QTime::currentTime().toString()
<< "Starting";
}
protected slots:
void catData () {
while (in->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(in->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
in->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
// Log stuff
qDebug() << QTime::currentTime().toString()
<< QString("I'm so happy! I've received a message from my dear friend %1:%2| %3.")
.arg(sender.toString()).arg(senderPort).arg(QString::fromLocal8Bit(datagram));
// Modify the datagramm
QByteArray out_datagram = "Hey, I've received a message: ";
out_datagram.append(datagram);
// send out the datagramm
out->write(out_datagram.data());
// restart the timer
timer->start(5000);
}
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QUdpSocketCat cat;
return a.exec();
}
#include "main.moc"
В одном терминале запускаем прослушивание порта 50081:
netcat -u -l -p 50081 localhost
Во втором сам саму программу и запись в порт (разбит на строки для удобства):
./qunetcat &
(sleep 2; echo "Hello there" | netcat -u --close localhost 50080)
&& wait
Примечание: используется GNU'тый netcat. У BSD'яшного и классического ключи могут отличаться.
[1] 11988
"15:45:12" Starting
"15:45:14" "I'm so happy! I've received a message from my dear friend 127.0.0.1:41603| Hello there\n."
"15:45:18" I'm so lonely... goodbye cruel world...
[1]+ Done
Как видно, первая и последняя строки от bash'а, дальше вывод о запуске и получении сообщения через две секунды. Затем завершение через 5.
Во втором терминале имеем ожидаемую строку:
Hey, I've received a message: Hello there
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
У меня подключено устройство (arduino), оно определяется и подключается к какому-нибудь COM-портуНомер порта можно изменить через Устройства и принтеры...
Здравствуйте, я понимаю что мой вопрос может прозвучать немного глупо и для опытного человека даже смешно, но мне нужна помощь в настройке...