Программа_1 бесконечно посылает 1 раз в секунду определенный набор байтов, а программа_2 его читает, обрабатывает и визуализирует.
Чтение по udp сетевых данных в программе_2:
QUdpSocket oUDPSocket;
QByteArray baoBufRecv;
unsigned short usSendPort;
QHostAddress haoLocalAddr, haoSenderAddr;
baoBufRecv.resize(65535);
haoLocalAddr.setAddress("127.0.0.1");
oUDPSocket.bind(haoLocalAddr, 5000);
connect(&oUDPSocket, SIGNAL(readyRead()), this, SLOT(sltReadDatagram()));
//-----------------------------------------------------------------------------
void Interaction::sltReadDatagram()
{
vReadDatagram();
}
//-----------------------------------------------------------------------------
void Interaction::vReadDatagram()
{
while (_oUDPSocket.hasPendingDatagrams())
{
long lSize = oUDPSocket.pendingDatagramSize();
oUDPSocket.readDatagram(baoBufRecv.data(), lSize, &haoSenderAddr, &usSendPort);
...
}
}
class Interaction: public QThread
{
}
попробуй вот так
auto size=oUDPSocket->bytesAvailable();
if(size>0 && oUDPSocket->hasPendingDatagrams())
{
}
А внутри указанного Вами выше кода (проверка bytesAvailable()) вызов vReadDatagram(), то есть этот код надо добавить в sltReadDatagram? Какой тогда в этом смысл, если я ставил принт в vReadDatagram и он переставал идти, значит переставала вызываться vReadDatagram, а следовательно sltReadDatagram(), а следовательно не было данных для чтения из сети (не срабатывает readyRead()) - или не так? У меня этот обмен тоже сделан в отдельном потоке (в примере упрощено) - а как это "сигналы не ловлю, просто вычитываю постоянно" - можете дать простейший пример? Наличие данных от программы_1 (работает на компе_1) в программе_2 (работает на компе_2) я проверял именно tcpdump-ом, так как комп_2 работает под ОС Ubuntu (wireshark думаю даст тот же положительный результат)
KuvshinoF, sltReadDatagram - это у тебя слот, и он по каким-то причинам перестаёт вызываться (точнее - не генерится сигнал)
его попробуй подпинывать в таймере (для теста сделай раз в секунду, чтобы чисто проверить)
//обработчик таймера
...()
{
sltReadDatagram();
}
QByteArray part;
while(1)
{
if(UDPServerSocket->state()==QUdpSocket::BoundState)
{
auto DatagramSize=UDPServerSocket->bytesAvailable();
if(DatagramSize>0 && UDPServerSocket->hasPendingDatagrams())
{
//DatagramSize - тут неплохо бы ограничить на некий максимальный размер, чтобы не словить краш от нехватки памяти
//DatagramSize=qMin<decltype(DatagramSize)>(20000,DatagramSize);
part.resize(DatagramSize);
const auto readsize=UDPServerSocket->readDatagram(part.data(), part.size(),&host, &port);
if(readsize>=0)
{
part.resize(readsize);
}
}
}
//part - прочитанные данные
}
Спасибо за советы - обязательно попробую и "подпинывать" свою функцию, и Ваш вариант считывания сетевых данных. Но если это все не поможет, то что в программе может "глушить" сетевой обмен (который, я напоминаю, вначале все-таки идет и внезапно пропадает, хотя tcpdump и простенькая программа считывания данных из сети говорят о продолжении прихода данных от программы_1)? Или если Ваш вариант сетевого считывания поможет, то чем мой хуже? Кстати этот обмен стабильно работает, если сначала запустить программы (1 и 2), а только потом включить (коммутатор) сетевой обмен между ними, хотя по-хорошему порядок запуска программ и включения сетевого обмена должен быть не важен.
KuvshinoF, выводи в лог последовательность действий и все ошибки, которые можно посмотреть (в частности)
SocketError QAbstractSocket::error() const
SocketState QAbstractSocket::state() const
будет видно, вызывается ли слот вообще
У меня так сделано (в упрощенном виде):
class Interaction : public QThread
{
QUdpSocket oUDPSocket;
QByteArray baoBufRecv;
unsigned short usSendPort;
QHostAddress haoLocalAddr, haoSenderAddr;
...
}
Interaction::Interaction ()
{
baoBufRecv.resize(65535);
haoLocalAddr.setAddress("192.168.235.66");
oUDPSocket.bind(haoLocalAddr, 5000);
...
}
void Interaction::run()
{
connect(&oUDPSocket, SIGNAL(readyRead()), this, SLOT(sltReadDatagram()));
exec();
}
void Interaction::sltReadDatagram()
{
vReadDatagram(); // описана ранее в первом сообщении темы
}
MainCkass.cpp
Создается указатель на объект Interaction и вызывается его start() с приоритетом QThread::TimeCriticalPriority
KuvshinoF, да вроде всё, что нужно имеется. Остаётся выяснить, поможет ли подпинывание слота "вручную". Ну и лог вести
Спасибо, буду пробовать, когда предоставится такая возможность.
И функция vReadDatagram(), и слот sltReadDatagram являются членами класса Interaction - наследника от QThread, в первом своем сообщении я опечатался (не Mainwindow конечно)
qDebug() << "место где выводится ид потока " << QThread::currentThreadId();
Гость_Гость_*: а почему так (почему члены класса-отдельного QThread-потока будут находиться в потоке, создавшем этот QThread (объект создается в Mainclass))? и что из этого следует? как сделать верно и что мне даст знание id моего QThread-а?
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)