Russian Qt Forum
Сентябрь 30, 2024, 10:28 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Не срабатывает слот при получении сигналk  (Прочитано 4145 раз)
___Cepera___
Гость
« : Март 10, 2016, 14:54 »

Qt4.8.7. Такая ситуация, есть серверный udpsocket, клиент шлет сообщение, сервер прочитал пришедшее сообщение от клиента, отправил его на обработку в другой поток, и при определенных перешедших данных, начинаем бесконечно слать обратно клиенту ответные сообщения. Остановка отправки сообщений осуществляется специальным сообщением от клиента, так вот когда клиент отправляет сообщение на остановку непрерывной передачи, серверный udpsocket не переходит в слот обработки. Как можно поставить приоретет на выполнения слота по пришедшему сигналу? ну или вообще может какие то предположения будут.
Все сообщения от сервера клиенту доходят. С 1 сообщением тоже все работает хорошо. Поток по сути ни как не влияет. Отправка ответного сообщения идет не из потока. В потоке только обработка. Единственный вариант, который мне пришел в голову, в ручную проверять udpsocket на наличее данных при бесконечной отправки сообщений.
« Последнее редактирование: Март 10, 2016, 15:06 от ___Cepera___ » Записан
Bepec
Гость
« Ответ #1 : Март 10, 2016, 15:10 »

"бесконечно отправляет" - а время для обработки приходящего сообщения есть, или же у вас там for стоит голый?
Записан
___Cepera___
Гость
« Ответ #2 : Март 10, 2016, 15:20 »

Бесконечная отправка работает так. При получении сообщения на бесконечнную отправку, в потоке ставится флаг. Потом формируется сообщение и шлется сигнал на отправку сформированного сообщения. После отправки сообщения клиенту, в поток шлется сигнал, поток смотрит, если стоит флаг на отправку сообщения, формирует его и опять шлет сигнал на отправку сформированного сообщения и так пока не придет сообщение от клиента на остановку.
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #3 : Март 10, 2016, 16:00 »

добавьте какую-нибудь задержку, хоть в 1 миллисекунду
Записан

___Cepera___
Гость
« Ответ #4 : Март 10, 2016, 16:27 »

Самое смешное ставил задержку в 1 и более секунду через sleep в потоке, не помогало, ответные сообщения приходили дольше, но сообщения клиента так же не приходили, но поставил в 1 секунду таймер в основном потоке программы перед отправкой сообщения, заработало отлично)
Странно, но получается наверное сокет не успевает освободиться Потому что делал, чтобы сервер отправлял 200 сообщений, сообщение серверу на остановку приходило после отправки этих 200 сообщений. Программа сервер еще пока идет отправка без таймера зависает,  хотя не должна. Можно как то решить еще эту проблему без таймера?
Записан
Bepec
Гость
« Ответ #5 : Март 10, 2016, 19:58 »

Поправив ваш код, можно совершить всё что угодно, "даже в космос полететь". Но без предмета разговора делать нечего Веселый
Записан
___Cepera___
Гость
« Ответ #6 : Март 13, 2016, 20:27 »

Код выложить не могу, поэтому накидал простенькое приложение для тестирования на сколько возможно максимум в windows в секунду отправлять udp сообщений получилось около 15000.
Такая проблема, перенес отправку сообщений в отдельный поток, ставил там задержку, поставил потоку низкий приоритет, он все равно не дает работать основному потоку. В основном потоке запускается таймер на 1 секунду, но поток для отправки не дает сработать таймауту. Ниже прилагаю код. Делал отправку по таймауту таймера в 1 милисекунду работает хорошо, но странно,что когда делал через сон потока в 1 секунду, поток опять блокирует основной поток программы. Посоветуйте как правильно реализовать отправку udp сообщений, чтобы выжимать максимум в windows и чтобы можно было останавливать отправку.
Код:
#include "server.h"

Server::Server() :
    QObject()
{
    udpSock = new QUdpSocket();
    connect(udpSock, SIGNAL(readyRead()), this, SLOT(readUDP()));
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(timeout()));
    stopSend = new QTimer(this);
    connect(stopSend, SIGNAL(timeout()), this, SLOT(stopSendMess()));
    stop = true;
}
Server :: ~Server()
{
    udpSock->close();
}
bool Server :: bind_port(quint16 port, quint16 _serverPort, QHostAddress _serverAddress)
{

    if(udpSock->bind(port))
    {
        serverPort = _serverPort;
        serverAddress = _serverAddress;
        emit message("Подключение выполнено");
        udpsend = new UdpSend(serverAddress, serverPort);\
        connect(udpsend, SIGNAL(finished()), udpsend, SLOT(deleteLater()));
        connect(this, SIGNAL(start(QUdpSocket*,bool*)), udpsend, SLOT(send(QUdpSocket*,bool*)));
        return true;
    }
    else
        emit message("Подключение не выполнено");
    return false;
}

void Server::close_port()
{
    udpSock->close();
    udpsend->quit();
    emit message("Отключение выполнено");
}

void Server :: send_data_UDP(QString text)
{
    QByteArray _message = text.toLocal8Bit();
    QDataStream out(&_message, QIODevice::WriteOnly);
    out.setVersion(QDataStream :: Qt_4_8);
    udpSock->writeDatagram(_message, serverAddress, serverPort);
}
void Server :: readUDP()
{
    QByteArray receiveData;
    int nbytes = udpSock->pendingDatagramSize();
    receiveData.resize(nbytes);
    udpSock->readDatagram (receiveData.data(), nbytes);
    emit append_message(receiveData);
    if(receiveData == "stop")
        stop = true;
    else if(stop)
    {
        stop = false;
        stopSend->start(1000);
        emit start(udpSock, &stop);

    }

}
void Server :: endless_send() //Через таймер работает хорошо, интерфейс не блокируется
{
    if(!stop)
        timer->start(1);
}
void Server :: timeout()
{
    timer->stop();
    send_data_UDP("hello");
    endless_send();

}
void Server :: stopSendMess()
{
    udpSock->close();
    stop = true;
    stopSend->stop();
}


Поток для отправки
Код:
#include "udpsend.h"

UdpSend::UdpSend(QHostAddress _address, quint16 _port) :
    QThread()
{
    address = _address;
    port = _port;
    start(QThread :: LowestPriority);
}
void UdpSend :: run()
{
    exec();
}
void UdpSend :: send(QUdpSocket * udpSocket, bool * send)
{
    QString text = "hello";
    while(*send == false)
    {
        msleep(1);
        QByteArray _message = text.toLocal8Bit();
        QDataStream out(&_message, QIODevice::WriteOnly);
        out.setVersion(QDataStream :: Qt_4_8);
        udpSocket->writeDatagram(_message, address, port);
    }
}

« Последнее редактирование: Март 13, 2016, 22:54 от ___Cepera___ » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.046 секунд. Запросов: 23.