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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: TCP. отключение от сервера.  (Прочитано 16736 раз)
meandnano
Гость
« : Май 01, 2010, 16:40 »

здравствуйте. такой вопрос:
Есть клиент-сервеное приложение (TCP). При отключении клиента от сервера мне неоюходимо знать, какой именно клиент отключился. Если клиент уходит, посредством нажатия специально обученой кнопки, тогда никаких проблем - программа сначала отсылает серверу соответствующее сообщение. Но необходимо обработать уход клиента и при случайном разрыве.
Пытался соеденить disconnected() клиента cо слотом в котором делается QTcpSocket *X = (QTcpSocket*) sender(); - но так не прокатывает, при отключении сервер вылетает с сегфолтом.

Собственно нужно это за тем, чтобы удалить соответствующий элемент из контейнера с клиентами QVector<QTcpSocket*> и оповестить всех остальных клиентов.
Достаточно знать хотя бы socketDescriptor клиента.
Есть ли варианты?
Записан
BRE
Гость
« Ответ #1 : Май 01, 2010, 16:54 »

Есть ли варианты?
Покажи, что делается в слоте, который подключен к disconnected.
Думаю ты просто разрушаешь объект delete, если это так, то так делать нельзя. В общем покажи, что бы мы не гадали.  Подмигивающий
Записан
garryHotDog
Гость
« Ответ #2 : Май 01, 2010, 18:12 »

попробуй обрабатывать сигнал сокета
Цитировать
void QAbstractSocket::stateChanged ( QAbstractSocket::SocketState socketState )   [signal]
и при отключении сокета посылать новый сигнал!

например:
Код:

// регистрация типа
qRegisterMetaType<QAbstractSocket::SocketState>("QAbstractSocket::SocketState");
// изменение состояние сокета.
connect(&m_Socket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(slot_OnSocketChangeState(QAbstractSocket::SocketState)));
...
...
...
//------------------------------------------------------------
// изменение состояние сокета. [слот]
//------------------------------------------------------------
void CMyClass::slot_OnSocketChangeState(QAbstractSocket::SocketState state)
{
switch (state)
{
                case (QAbstractSocket::UnconnectedState):
case (QAbstractSocket::ClosingState):
{
                                // пошлем наш сигнал
                                emit Mysignal(socketID);
break;
}
        }
}

Записан
meandnano
Гость
« Ответ #3 : Май 01, 2010, 18:37 »

BRE

вот соединение
Код:
void cserver::newconn(){
    QTcpSocket *Client = cServ->nextPendingConnection();
    connect(Client,SIGNAL(readyRead()),SLOT(readMess()));
    connect(Client,SIGNAL(disconnected()),this,SLOT(disconn()));

еще была строка:
connect(Client,SIGNAL(disconnected()),Client,SLOT(deleteLater()));
но убрал по случаю соединения с disconn();

Код:
void cserver::disconn(){
    QTcpSocket *Client = (QTcpSocket*) sender();
    int i,j,SID=Client->socketDescriptor();

    /*.....*/

    int _sid = sockets.indexOf(Client);  //то самое удаление
    sockets.remove(_sid);                  //  из QVector

   /*...*/

    delete Client;
}
вот этот код не работает и еще к тому же надо удалить объект, пославший дисконнект. сработает ли
delete sender(); ?

garryHotDog
спасибо, сейчас буду пробовать
Записан
BRE
Гость
« Ответ #4 : Май 01, 2010, 18:51 »

Попробуй так:
Код
C++ (Qt)
void cserver::disconn(){
   QTcpSocket *Client = qobject_cast<QTcpSocket*>( sender() );
   if( !Client )
    return;
 
   int i,j,SID=Client->socketDescriptor();
 
   /*.....*/
 
   int _sid = sockets.indexOf(Client);  //то самое удаление
   sockets.remove(_sid);                  //  из QVector
 
  /*...*/
 
   Client->deleteLater();
}
 
Записан
meandnano
Гость
« Ответ #5 : Май 01, 2010, 19:02 »

Попробуй так:
Код
C++ (Qt)
void cserver::disconn(){
   QTcpSocket *Client = qobject_cast<QTcpSocket*>( sender() );
   if( !Client )
    return;
}
 


попробую

garryHotDog

компилятор ругается на регистрацию типа - заявляет
Цитировать
error: too few template-parameter-lists
хотя запись соответствует мануалу
Записан
BRE
Гость
« Ответ #6 : Май 01, 2010, 19:05 »

попробую

Главное все же это: Улыбающийся
Код
C++ (Qt)
void cserver::disconn(){
...
   Client->deleteLater();
}
 
Записан
meandnano
Гость
« Ответ #7 : Май 01, 2010, 19:17 »

BRE
вести с фонтов:
в disconn() обоими способами:
1) QTcpSocket *Client = (QTcpSocket*) sender();
2) QTcpSocket *Client = qobject_cast<QTcpSocket*>( sender() );
и Client->deleteLater() на конце

все проходит без ошибок, НО не правильно - отладка показывает, что Client->socketDescriptor()=-1
Записан
garryHotDog
Гость
« Ответ #8 : Май 01, 2010, 19:38 »

у меня регистрация вынесена в конструктор класса!
Записан
BRE
Гость
« Ответ #9 : Май 01, 2010, 19:46 »

все проходит без ошибок, НО не правильно - отладка показывает, что Client->socketDescriptor()=-1
А что ты ожидаешь там увидеть, при приеме сигнала disconnected. Сокет уже закрыт.
Записан
meandnano
Гость
« Ответ #10 : Май 01, 2010, 20:13 »

А что ты ожидаешь там увидеть, при приеме сигнала disconnected. Сокет уже закрыт.

ну я предполагал, что так и будет, но вся соль то как раз в том, что мне надо socketID получить от уходящего клиента.

garryHotDog
сделал так:
Код
C++ (Qt)
void cserver::exiting( QAbstractSocket::SocketState state ){
   switch( state ){
   case ( QAbstractSocket::ClosingState ):{
        QTcpSocket *Client = ( QTcpSocket* ) sender();
        emit hasGone( Client->socketDescroptor() );
        break;
       }
   }
}
 

правильно ли? Client->socketDescroptor() возвращает -1
Записан
garryHotDog
Гость
« Ответ #11 : Май 01, 2010, 22:41 »

Код
C++ (Qt)
QTcpSocket *Client = ( QTcpSocket* ) sender();
 
ты здесь корректно получаешь указатель на Client ? попробуем добавить
Код
C++ (Qt)
if( Client )
{
  int id=Client->socketDescroptor();
}
else{}
 

а получить другие параметры от Client можно? например адрес или порт??


цитатка из ассиста
Цитировать
The socket descriptor is not available when QAbstractSocket is in UnconnectedState.
« Последнее редактирование: Май 01, 2010, 22:49 от garryHotDog » Записан
meandnano
Гость
« Ответ #12 : Май 01, 2010, 22:49 »

В if( Client ) заходит, но id = -1
Записан
garryHotDog
Гость
« Ответ #13 : Май 01, 2010, 22:50 »

Цитировать
а получить другие параметры от Client можно? например адрес или порт??
Записан
meandnano
Гость
« Ответ #14 : Май 01, 2010, 23:03 »

у меня все на socketID завязано.
загвоздка в отм, что у меня есть QVector<QTcpSocket*> - где все они лежат. сделано это было с целью отправлять сообщения всем или только некоторым, путем перебора элементов в векторе.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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