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

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

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: Проблема с удалением сокета  (Прочитано 23553 раз)
BRE
Гость
« Ответ #15 : Октябрь 29, 2009, 23:39 »

ок,тогда можно глупый вопрос.как реализовать его удаление?я вот щас попытался сделать чтот типа такого
    connect(sock_thread,SIGNAL(terminated())),sock_thread,SLOT(deleteLater()));

ну естестно не сработало.
Почему terminated?
Нитка нормально завершается, нужно использовать finished.
Записан
xaleva
Гость
« Ответ #16 : Октябрь 30, 2009, 00:00 »

 :)прогресс,терь память после дисконнекта освобождается,но ток на половину того,что занималось на этот поток.т.е при создании увеличение 0.2 мб,а при дисконнекте уменьшение на 0.1
Записан
BRE
Гость
« Ответ #17 : Октябрь 30, 2009, 00:02 »

:)прогресс,терь память после дисконнекта освобождается,но ток на половину того,что занималось на этот поток.т.е при создании увеличение 0.2 мб,а при дисконнекте уменьшение на 0.1

Осталось удалять объект socket и думаю все будет нормально.
Его можно создавать на стеке:
Код
C++ (Qt)
void socket_thread::run()
{
   QTcpSocket socket;
   if (!socket.setSocketDescriptor(descriptor)) {
       emit signalSocketError(socket.peerAddress().toString(),"error");
       return;
   }
   ...
 
Записан
xaleva
Гость
« Ответ #18 : Октябрь 30, 2009, 00:16 »

Да,ток хотел добавить что это скорее всего происходит из за того что не удаляю этот объект.Ок,а я вот пробывал удалить таким образом:
    connect(this,SIGNAL(finished()),socket,SLOT(deleteLater()));

почему этот вариант не катит?
Записан
BRE
Гость
« Ответ #19 : Октябрь 30, 2009, 00:24 »

Да,ток хотел добавить что это скорее всего происходит из за того что не удаляю этот объект.Ок,а я вот пробывал удалить таким образом:
    connect(this,SIGNAL(finished()),socket,SLOT(deleteLater()));

почему этот вариант не катит?
Как я думаю, это из-за того, что deleteLater удаляет объект при очередном входе в event loop. А так как нитка уже завершилась, то ее event loop уже остановлен.
Записан
xaleva
Гость
« Ответ #20 : Октябрь 30, 2009, 00:28 »

 :)ок,спасибо большое,будем разбираться,доброй ночи Улыбающийся
Записан
xaleva
Гость
« Ответ #21 : Октябрь 30, 2009, 08:57 »

Ок,терь я делаю так:
void socket_thread::run()
{
    QTcpSocket socket;
    if (!socket.setSocketDescriptor(descriptor)) {
        emit signalSocketError(socket.peerAddress().toString(),"error");
        return;
    }
    com=new socket_coming(&socket);
......
}

А вот это ему терь не нравится:

socket_coming::~socket_coming()
{
    delete socket;
}


Записан
BRE
Гость
« Ответ #22 : Октябрь 30, 2009, 08:58 »

Ок,терь я делаю так:
void socket_thread::run()
{
    QTcpSocket socket;
    if (!socket.setSocketDescriptor(descriptor)) {
        emit signalSocketError(socket.peerAddress().toString(),"error");
        return;
    }
    ip_address=socket.peerAddress().toString();
    com=new socket_coming(&socket);
......
}

А вот это ему терь не нравится:

socket_coming::~socket_coming()
{
    delete socket;
}
Сокет создается на стеке, его больше не надо удалять delete, он сам разрушиться при выходе из run.
Записан
xaleva
Гость
« Ответ #23 : Октябрь 30, 2009, 09:02 »

 Улыбающийся тогда прихожу к тому,что он мне пишет

QSocketNotifier: Multiple socket notifiers for same socket 1592 and type Read

ну и память соотвестно на половину удаляется
Записан
xaleva
Гость
« Ответ #24 : Октябрь 30, 2009, 09:05 »

Приведу на всякий случай конечный код.В главном потоке:

void main_widget::slotComingNewConnection()
{
    coming_socket=serverComing->nextPendingConnection();
    socket_thread *sock_thread=new socket_thread(coming_socket->socketDescriptor());
   connect(sock_thread,SIGNAL(signalUpdateTerminals(QString,QString)),this,SLOT(slotUpdateComingTerminalsList(QString,QString)),Qt::QueuedConnection);
    connect(sock_thread,SIGNAL(signalClearTerminals(QString,QString)),this,SLOT(slotClearComingTerminalsList(QString,QString)),Qt::QueuedConnection);
    connect(sock_thread,SIGNAL(signalComingReadyWrite(QString)),this,SLOT(slotCreateOutGoing(QString)),Qt::QueuedConnection);
    connect(this,SIGNAL(signalWriteComing(QString,QString)),sock_thread,SLOT(slotComingWrite(QString,QString)));
    connect(sock_thread,SIGNAL(signalCloseThread(QString)),this,SLOT(slotBeforeCloseSocket(QString)),Qt::QueuedConnection);
    connect(sock_thread,SIGNAL(signalSocketError(QString,QString)),this,SLOT(slotComingSocketError(QString,QString)),Qt::QueuedConnection);
    connect(sock_thread,SIGNAL(signalCloseThread()),sock_thread,SLOT(quit()));
    connect(sock_thread,SIGNAL(finished()),sock_thread,SLOT(deleteLater()));
    sock_thread->start();
}

В потоке:

void socket_thread::run()
{
    QTcpSocket socket;
    if (!socket.setSocketDescriptor(descriptor)) {
        emit signalSocketError(socket.peerAddress().toString(),"error");
        return;
    }
    com=new socket_coming(&socket);
    connect(com,SIGNAL(socketReadyWriteSignal(QString)),this,SLOT(slotComingReadyWrite(QString)));
    connect(this,SIGNAL(signalComingWrite(QString,QString)),com,SLOT(slotWrite(QString,QString)));
    connect(com,SIGNAL(signalUpdateTerminals(QString,QString)),this,SLOT(slotUpdateTerminals(QString,QString)));
    connect(com,SIGNAL(signalClearTerminals(QString,QString)),this,SLOT(slotClearTerminals(QString,QString)));
    connect(com,SIGNAL(signalError(QString,QString)),this,SLOT(slotSocketError(QString,QString)));
    connect(com,SIGNAL(socketDisconnected()),this,SLOT(closeThread()));
    exec();
}

socket_thread::~socket_thread()
{
    delete com;
}

В классе:

socket_coming::socket_coming(QTcpSocket *soc):QObject(),socket(soc),val("")
{
    connect(socket,SIGNAL(readyRead()),this,SLOT(slotReadyRead()));
    connect(socket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(slotSocketError(QAbstractSocket::SocketError)));
    connect(socket,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));
}

Записан
BRE
Гость
« Ответ #25 : Октябрь 30, 2009, 09:09 »

Возможно, это из-за того, что объект com (класса socket_coming), который использует этот сокет еще не разрушен.
Можно попробовать создавать его также на стеке.
Покажи как разрушаются объекты com.

Код
C++ (Qt)
void socket_thread::run()
{
   QTcpSocket socket;
   if (!socket.setSocketDescriptor(descriptor)) {
       emit signalSocketError(socket.peerAddress().toString(),"error");
       return;
   }
   socket_coming com(&socket);
   connect(&com,SIGNAL(socketReadyWriteSignal(QString)),this,SLOT(slotComingReadyWrite(QString)));
   connect(this,SIGNAL(signalComingWrite(QString,QString)),com,SLOT(slotWrite(QString,QString)));
   connect(&com,SIGNAL(signalUpdateTerminals(QString,QString)),this,SLOT(slotUpdateTerminals(QString,QString)));
   connect(&com,SIGNAL(signalClearTerminals(QString,QString)),this,SLOT(slotClearTerminals(QString,QString)));
   connect(&com,SIGNAL(signalError(QString,QString)),this,SLOT(slotSocketError(QString,QString)));
   connect(&com,SIGNAL(socketDisconnected()),this,SLOT(closeThread()));
   exec();
}
 
socket_thread::~socket_thread()
{
}
 
Записан
xaleva
Гость
« Ответ #26 : Октябрь 30, 2009, 09:16 »

 Улыбающийся :)точно,все терь 100% работает,большое спасибо BRE Улыбающийся
Записан
BRE
Гость
« Ответ #27 : Октябрь 30, 2009, 09:20 »

Несколько мыслей:
* По мне, так лучше чтобы объект socket был членом класса socket_coming и создавался соответственно в его конструкторе.
* Между потоками можно передавать сами объекты QTcpSocket (вместо дескрипторов), главное сделать этому объекту moveToThread в поток которому он передается.
« Последнее редактирование: Октябрь 30, 2009, 09:35 от BRE » Записан
xaleva
Гость
« Ответ #28 : Октябрь 30, 2009, 09:44 »

Согласен.Вот пытаюсь переделать по поводу первого замечания,вот код:

В главном:

void main_widget::slotComingNewConnection()
{
    coming_socket=serverComing->nextPendingConnection();
    socket_thread *sock_thread=new socket_thread(coming_socket->socketDescriptor());
    connect(sock_thread,SIGNAL(signalUpdateTerminals(QString,QString)),this,SLOT(slotUpdateComingTerminalsList(QString,QString)),Qt::QueuedConnection);
    connect(sock_thread,SIGNAL(signalClearTerminals(QString,QString)),this,SLOT(slotClearComingTerminalsList(QString,QString)),Qt::QueuedConnection);
    connect(sock_thread,SIGNAL(signalComingReadyWrite(QString)),this,SLOT(slotCreateOutGoing(QString)),Qt::QueuedConnection);
    connect(this,SIGNAL(signalWriteComing(QString,QString)),sock_thread,SLOT(slotComingWrite(QString,QString)));
    connect(sock_thread,SIGNAL(signalCloseThread(QString)),this,SLOT(slotBeforeCloseSocket(QString)),Qt::QueuedConnection);
    connect(sock_thread,SIGNAL(signalSocketError(QString,QString)),this,SLOT(slotComingSocketError(QString,QString)),Qt::QueuedConnection);
    connect(sock_thread,SIGNAL(signalCloseThread()),sock_thread,SLOT(quit()));
    connect(sock_thread,SIGNAL(finished()),sock_thread,SLOT(deleteLater()));
    sock_thread->start();
}

В потоке:
socket_thread::socket_thread(int descr):QThread()
{
    descriptor=descr;
}

void socket_thread::run()
{
    socket_coming com(descriptor);
    connect(&com,SIGNAL(socketReadyWriteSignal(QString)),this,SLOT(slotComingReadyWrite(QString)));
    connect(this,SIGNAL(signalComingWrite(QString,QString)),&com,SLOT(slotWrite(QString,QString)));
    connect(&com,SIGNAL(signalUpdateTerminals(QString,QString)),this,SLOT(slotUpdateTerminals(QString,QString)));
    connect(&com,SIGNAL(signalClearTerminals(QString,QString)),this,SLOT(slotClearTerminals(QString,QString)));
    connect(&com,SIGNAL(signalError(QString,QString)),this,SLOT(slotSocketError(QString,QString)));
    connect(&com,SIGNAL(socketDisconnected()),this,SLOT(closeThread()));
    exec();
}

В классе:

socket_coming::socket_coming(int descr):QObject(),descriptor(descr),val("")
{
    socket=new QTcpSocket;
    socket->setSocketDescriptor(descriptor);
    connect(socket,SIGNAL(readyRead()),this,SLOT(slotReadyRead()));
    connect(socket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(slotSocketError(QAbstractSocket::SocketError)));
    connect(socket,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));
}

socket_coming::~socket_coming()
{
    delete socket;
}

Выводит опять ту ошибку:
QSocketNotifier: Multiple socket notifiers for same socket 3644 and type Read

« Последнее редактирование: Октябрь 30, 2009, 10:00 от xaleva » Записан
xaleva
Гость
« Ответ #29 : Октябрь 30, 2009, 10:08 »

 :)Возникла такая мысль,что это происходит потому,что сокет не удаляется,а он не удаляется потому что класс потока не удаляется сразу,там ведь deleteLater().А как решить иначе,не знаю.
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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