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

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

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

Добрый вечер всем.У меня возникла следующая проблема.Создаю сервер.Новые сокеты выношу в отдельные потоки.Делаю это в общем то как принято,через дескрипторы:


void socket_thread::run()
{
    if (!socket->setSocketDescriptor(descriptor)) {
        emit signalSocketError(socket->peerAddress().toString(),"error");
        return;
    }
    com=new socket_coming(socket);
    connect(...);
    exec();
}

Класс socket_coming - мой класс,в котором я произвожу все действия с сокетом,там же есть коннект на дисконнект сокета,и в слоте,который врубается на дисконнект пишу delete socket; т.е удаляю объект сокета.При этом после нескольких(примерно 10) дисконектов прога падает.Если убрать строчку удаления все работает,но память растет,и иногда вылетает ошибка

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

Я так понимаю,я не правильно удаляю сокет.В чем может быть проблема?



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

Ты в слоте, который вызывается сигналом сокета, его удаляешь?
Побольше кода покажи.

Попробуй вместо удаления использовать:
Код
C++ (Qt)
socket->deleteLater();
Записан
xaleva
Гость
« Ответ #2 : Октябрь 29, 2009, 22:31 »

Да.Насчет deleteLater пробовал,как понимаю,он не удаляет,память не освобождается.
по поводу кода приведу фрагмент из того класса:

socket_coming::socket_coming(QTcpSocket *soc):QObject(),socket(soc)
{
//тут коннекты на сигналы от сокета,в том числе и дисконнект
    connect(...);
    connect(...);
}

//А это тот самый слот на дисконнект
void socket_coming::slotDisconnected()
{
    disconnect(..);
    disconnect(..);
    delete socket;
    emit socketDisconnected();
}

сам объект этого класса,который создается в классе потока тоже в конце удаляю в деструкторе.В этом классе тоже ставил удаление сокета в деструктор-разницы нет
Записан
BRE
Гость
« Ответ #3 : Октябрь 29, 2009, 22:38 »

Боюсь спросить, это программа управления нашей орбитальной группировкой?  Подмигивающий
Можно по-подробней?

Это выглядит примерно так?
Код
C++ (Qt)
socket_coming::socket_coming(QTcpSocket *soc):QObject(),socket(soc)
{
connect( socket, SIGNAL( disconnected() ), SLOT( slotDisconnected() ) );
}
 
void socket_coming::slotDisconnected()
{
   disconnect(..);
   disconnect(..);
   delete socket;
   emit socketDisconnected();
}
 
Т.е. ты пытаешься разрушить сокет из обработчика его же сигнала?
Записан
xaleva
Гость
« Ответ #4 : Октябрь 29, 2009, 22:43 »

 ;)не совсем.

Да,ты прав,но удаление я ведь ставил и в деструктор класса.все равно прога падала.
Записан
BRE
Гость
« Ответ #5 : Октябрь 29, 2009, 22:46 »

В каком потоке создается объект QTcpSocket?
Как он передается в поток?
Записан
xaleva
Гость
« Ответ #6 : Октябрь 29, 2009, 22:53 »

Спасиб большое Улыбающийся

перенес эти строки в run
    socket=new QTcpSocket;
    socket->moveToThread(this);

терь вроде все ок,еще раз большое спасиб Улыбающийся

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

Спасиб большое Улыбающийся

перенес эти строки в run
    socket=new QTcpSocket;
    socket->moveToThread(this);

терь вроде все ок,еще раз большое спасиб Улыбающийся
Если создаешь в run, то это уже контекст этого потока. moveToThread излишен.
Записан
xaleva
Гость
« Ответ #8 : Октябрь 29, 2009, 22:58 »

Да,эм...кажись проблема не решилась  Улыбающийся ночью чтот голова плохо работает :)так вот,сам сокет создается в главном потоке,а передается вот так:

void socket_thread::run()
{
    socket=new QTcpSocket;
    socket->moveToThread(this);
    if (!socket->setSocketDescriptor(descriptor)) {
        emit signalSocketError(socket->peerAddress().toString(),"error");
        return;
    }
    com=new socket_coming(socket);
}

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

Покажи код.  Улыбающийся
Записан
xaleva
Гость
« Ответ #10 : Октябрь 29, 2009, 23:06 »

код из главного потока:

void main_widget::slotComingNewConnection()
{
    coming_socket=serverComing->nextPendingConnection();
    updateActiveTerminals();
    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()),Qt::QueuedConnection);
    sock_thread->start();
}


код из потока:

socket_thread::socket_thread(int descr):QThread()
{
    descriptor=descr;
}

void socket_thread::run()
{
    socket=new QTcpSocket;
    socket->moveToThread(this);
    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()),Qt::DirectConnection);
    exec();
}

void socket_thread::closeThread()
{
    disconnect(com,SIGNAL(socketReadyWriteSignal(QString)),this,SLOT(slotComingReadyWrite(QString)));
    disconnect(this,SIGNAL(signalComingWrite(QString,QString)),com,SLOT(slotWrite(QString,QString)));
    disconnect(com,SIGNAL(signalUpdateTerminals(QString,QString)),this,SLOT(slotUpdateTerminals(QString,QString)));
    disconnect(com,SIGNAL(signalClearTerminals(QString,QString)),this,SLOT(slotClearTerminals(QString,QString)));
    disconnect(com,SIGNAL(signalError(QString,QString)),this,SLOT(slotSocketError(QString,QString)));
    disconnect(com,SIGNAL(socketDisconnected()),this,SLOT(closeThread()));
    delete com;
    emit signalCloseThread(ip_address);
    emit signalCloseThread();
}

код из класса socket_coming:

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()));
}

void socket_coming::slotDisconnected()
{
    disconnect(socket,SIGNAL(readyRead()),this,SLOT(slotReadyRead()));
    disconnect(socket,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));
    emit socketDisconnected();
}

socket_coming::~socket_coming()
{
    delete socket;
}
Записан
BRE
Гость
« Ответ #11 : Октябрь 29, 2009, 23:11 »

Это не смущает?  Подмигивающий
Код
C++ (Qt)
void socket_thread::run()
{
   ...
   com=new socket_coming(socket);
   ...
   connect(com,SIGNAL(socketDisconnected()),this,SLOT(closeThread()),Qt::DirectConnection);
}
 
void socket_thread::closeThread()
{
   ...
   delete com;
   ...
}
 
Записан
xaleva
Гость
« Ответ #12 : Октябрь 29, 2009, 23:19 »

 Улыбающийся :)смущает,убрал,поставил в деструктор потока,и пробывал ставить после exec(); все работает,прога не падает,но память растет.не знаете случайно почему?
Записан
BRE
Гость
« Ответ #13 : Октябрь 29, 2009, 23:23 »

Улыбающийся :)смущает,убрал,поставил в деструктор потока,и пробывал ставить после exec(); все работает,прога не падает,но память растет.не знаете случайно почему?

Код
C++ (Qt)
void main_widget::slotComingNewConnection()
{
   ...
   socket_thread *sock_thread=new socket_thread(coming_socket->socketDescriptor());
   ...
   connect(sock_thread,SIGNAL(signalCloseThread()),sock_thread,SLOT(quit()),Qt::QueuedConnection);
   ...
}
 
А где удаление объекта sock_thread?
Записан
xaleva
Гость
« Ответ #14 : Октябрь 29, 2009, 23:37 »

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

ну естестно не сработало.
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


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