crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в Пропадание сетевого обмена
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
KuvshinoF Дата 1.5.2020, 21:34
  Гость_Гость_*: а почему так (почему члены класса-отдельного QThread-потока будут находиться в потоке, создавшем этот QThread (объект создается в Mainclass))? и что из этого следует? как сделать верно и что мне даст знание id моего QThread-а?
Гость Дата 1.5.2020, 19:41
 
Цитата(KuvshinoF @ 18.4.2020, 22:59) *
class Interaction : public QThread
{
  QUdpSocket oUDPSocket;
  QByteArray baoBufRecv;

В таком варианте у вас всегда объект oUDPSocket и baoBufRecv будут находиться в потоке, который создал экземпляр класса Interaction. Чтобы всё это отследить вставьте вывод текущего потока
qDebug() << "место где выводится ид потока " << QThread::currentThreadId();
KuvshinoF Дата 20.4.2020, 11:34
  И функция vReadDatagram(), и слот sltReadDatagram являются членами класса Interaction - наследника от QThread, в первом своем сообщении я опечатался (не Mainwindow конечно)
Алексей1153 Дата 20.4.2020, 11:03
 
Цитата(KuvshinoF @ 19.4.2020, 0:59) *
vReadDatagram(); // описана ранее в первом сообщении темы


так а где этот слот находится то ? В потоке или в главном окне? У меня смутные подозрения, что с синхронизацией напутано тут

не вижу вызов moveToThread нигде


Цитата(KuvshinoF @ 19.4.2020, 0:59) *
class Interaction : public QThread
{
  QUdpSocket oUDPSocket;
  QByteArray baoBufRecv;

у тебя рабочий объект и поток - одним классом. Тогда уж лучше унаследоваться от QThread

А в твоём варианте рабочий объект должен быть отдельно от потока. Рабочий объект создаётся в ОСНОВНОМ потоке, настраивается, затем перемещается в контекст потока. Я эту практику недолюбливаю, ей не пользуюсь, поэтому за деталями - в интернет ) Я обычно наследуюсь и не испытываю этот гемор
KuvshinoF Дата 20.4.2020, 10:54
  Спасибо, буду пробовать, когда предоставится такая возможность.
Алексей1153 Дата 19.4.2020, 21:21
  KuvshinoF, да вроде всё, что нужно имеется. Остаётся выяснить, поможет ли подпинывание слота "вручную". Ну и лог вести
KuvshinoF Дата 18.4.2020, 22:59
  У меня так сделано (в упрощенном виде):
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

Алексей1153 Дата 18.4.2020, 8:08
  KuvshinoF, выводи в лог последовательность действий и все ошибки, которые можно посмотреть (в частности)

SocketError QAbstractSocket::error() const
SocketState QAbstractSocket::state() const

будет видно, вызывается ли слот вообще

Цитата(KuvshinoF @ 16.4.2020, 16:11) *
У меня этот обмен тоже сделан в отдельном потоке

и покажи, как это сделано, может сообщения потока не обрабатываются ? (QEventLoop)
KuvshinoF Дата 17.4.2020, 12:43
  Спасибо за советы - обязательно попробую и "подпинывать" свою функцию, и Ваш вариант считывания сетевых данных. Но если это все не поможет, то что в программе может "глушить" сетевой обмен (который, я напоминаю, вначале все-таки идет и внезапно пропадает, хотя tcpdump и простенькая программа считывания данных из сети говорят о продолжении прихода данных от программы_1)? Или если Ваш вариант сетевого считывания поможет, то чем мой хуже? Кстати этот обмен стабильно работает, если сначала запустить программы (1 и 2), а только потом включить (коммутатор) сетевой обмен между ними, хотя по-хорошему порядок запуска программ и включения сетевого обмена должен быть не важен.
Алексей1153 Дата 17.4.2020, 8:55
  KuvshinoF, sltReadDatagram - это у тебя слот, и он по каким-то причинам перестаёт вызываться (точнее - не генерится сигнал)

его попробуй подпинывать в таймере (для теста сделай раз в секунду, чтобы чисто проверить)

//обработчик таймера
...()
{
    sltReadDatagram();
}


Цитата(KuvshinoF @ 16.4.2020, 16:11) *
можете дать простейший пример


у меня сделано так:
(показано упрощённо)
в потоке, в бесконечном цикле внутри run
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 - прочитанные данные
}
Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 8.12.2021, 21:29