Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Qt] Передача указателя this через сигнал, Хороший ли это стиль? 
V
    Опции темы
null56
Дата 17.12.2008, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 6
Всего: 12



В общем такая ситуация:
У меня в системе висит сервер, который cпит в ожидании клиентов, задача была сделать такую вещь, что после подключения клиента:
1) создавался бы объект SslSocket
2) запускался бы startServerEncryption
3) Сервер продолжал ожидать других клиентов, но с этим клиентом он продолжил бы работать, после прихода от него определенных сигналов (encryption или ошибки), в общем, чтобы не ждать уведомления о начале шифрования

Что я сделал
1) У меня существует класс MySslSocket(обертка), который содержит в себе переменную QSSlSocket и осуществляет манипуляции с ней
a) для перехвата событий от QSslSocket я создал слоты у класса MySslSocket и соединил их с нужными мне сигналами QSSlSocket
б) класс обертка MySslSocket перехватив в обработчике - слоте событие от QSslSocket генерит свой сигнал, который передает указатель на собственный объект:
Код

emit sendObject(this);

2) Основной класс TcpSocket находится в ожидании соединения и имеет слот, обработчик событий созданных объектов класса MySslSocket.... и очередь, которая хранит, на всякий случай указатели на объекты, чтобы они не просто так витали в памяти, для принудительного удаления
приведу упрощенный код функции incomingConnection
Код

void SslServer :: incomingConnection(int socketDescriptor)
{
    SslSocket * p_new_client_connection = new SslSocket(socketDescriptor, ssl_socket :: SOCK_SERVER, this);
    if (p_new_client_connection->isOk())
    {
        mUnenclyptedQuery.append(p_new_client_connection);
        qDebug("query count: %d", mUnenclyptedQuery.count());
        connect(p_new_client_connection, SIGNAL(sendObject(SslSocket *)), this, SLOT(newSocketSignal(SslSocket *)));
        p_new_client_connection->startEncrypt(mSslCertificate, mSslKey);
    }
       иначе удаляю объект
}


Собственно, для пришедшего соединения создается объект, хранящий сокет и, в случае успеха:
1) адрес созданного объекта кладется в очередь
2) соединяются сингал передачи объекта и обработчик события
3) Запуск enryption

Код обработки события
Код

void SslServer :: newSocketSignal(SslSocket * pSslSocket)
{
    qDebug("Emited socket descriptor: %d", pSslSocket->getSocket()->socketDescriptor());
    disconnect(pSslSocket, 0, this, 0);
    mUnenclyptedQuery.removeOne(pSslSocket);
    qDebug("query count: %d", mUnenclyptedQuery.count());
}


Собственно манипуляции, в зависимости от состояния сокета +  удаление указателя из очереди и отвязка сигнала, так как сокетом будет заниматься уже другой объект из другого потока

Вопрос к вам: если понятна моя идея, скажите, не слишком ли грязная реализация для этого получается? Код рабочий и идея, в принципе оправдана, но может быть сущестуеют менее извращенные способы решения этой задачи на qt

Заранее благодарен за помощь
PM MAIL   Вверх
Purple_Light
Дата 17.12.2008, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 19.4.2007

Репутация: нет
Всего: нет



текст не осилил, но выскажусь, сильно не пинать.

Если тебе надо только получить информацию из объекта, то лучше передавать так называемый constant reference.

Например:
void object_operation_slot(const Object *obj);

Служебное слово const даст гарантию сохранности и неизменности объекта. Т.е. объект нельзя будет изменять и приэтом считывание с объекта будет быстре (кажись).

PM MAIL   Вверх
SABROG
Дата 17.12.2008, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Цитата(Purple_Light @  17.12.2008,  17:18 Найти цитируемый пост)
void object_operation_slot(const Object *obj);

А это разве не constant pointer ?


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Purple_Light
Дата 17.12.2008, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 19.4.2007

Репутация: нет
Всего: нет



Цитата(SABROG @ 17.12.2008,  17:25)
Цитата(Purple_Light @  17.12.2008,  17:18 Найти цитируемый пост)
void object_operation_slot(const Object *obj);

А это разве не constant pointer ?

да, может быть. У меня формулировка не точная.

update:
действительно 
const Object *obj - constant pointer
const Object &obj - constant reference

update 2:
если в интерфейсе функции указать значение как const, то основываять на этой информации компилятор попытается оптимизировать фукнцию для более быстрой работы. Но как он это делает, не могу найти. Буду рад если кто-нить кинет ссылку на инфу.

Это сообщение отредактировал(а) Purple_Light - 17.12.2008, 17:41
PM MAIL   Вверх
SABROG
Дата 17.12.2008, 18:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Я чего-то не понимаю или тут как-раз так и делается ?

Код

         void SslServer::incomingConnection(int socketDescriptor)
         {
             QSslSocket *serverSocket = new QSslSocket;
             if (serverSocket->setSocketDescriptor(socketDescriptor)) {
                 connect(serverSocket, SIGNAL(encrypted()), this, SLOT(ready()));
                 serverSocket->startServerEncryption();
             } else {
                 delete serverSocket;
             }
         }


Т.е. если приходит сигнал encrypted, то соединение зашифровано. И если зашифрованное соединение установить не удалось, то пускается сигнал sslErrors, после которого соединение с клиентом прерывается и QSslSocket можно мочкануть через sender()'a. Просто довольно странно использовать подобное:

Код

emit sendObject(this);


Если sender() и так известен.

Это сообщение отредактировал(а) SABROG - 17.12.2008, 18:52


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
null56
Дата 17.12.2008, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 6
Всего: 12



Вот вот вот вот ... да, именно про связь я спрашивал, а то уж слишком сложно получается у меня

То есть из слота мы можем узнать указатель вызывающего объекта????
Через функцию sender()?

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

Спасибо, это и узнавал.... я просто это ручками пытался сделать, от незнания... 

Просто я не хотел терять адрес созданного сокета и завязывал на очередь + на сигнал дважды вызываемый с целью передать адрес



Это сообщение отредактировал(а) null56 - 17.12.2008, 22:03
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.1320 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.