Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Передача дескриптора в поток, без сигналов, Не работает межпоточная передача 
V
    Опции темы
null56
Дата 30.6.2009, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Задача:
В основном потоке висит слушающий сокет (QSslSocket) и ожидает соединений. В дочернем работает обработчик событий, который проверяет свою очередь на поступление новых дескрипторов сокетов.
При поступлении нового сокета, основной поток засовывает дескриптор (число int) в очередь дочернего потока и продолжает слушать, дочерний поток периодами просматривает очередь и вытаскивает оттуда дескриптор сокета, затем создает объект QSslSocket и работает непосредственно с ним.... очередь реализована в виде нитебезопасного QList<int>

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

class TcpServer : public QTcpServer
{
public:
    TcpServer();
     void incomingConnection ( int socketDescriptor );
private:
    Thread m_SocketThread;
};


Код

TcpServer::TcpServer()
{
    m_SocketThread.start();
}

void
TcpServer :: incomingConnection ( int socketDescriptor )
{
    qDebug("New socket: %d", socketDescriptor);
    m_SocketThread.add(socketDescriptor);
}


Дочерний поток
Код

class Thread : public QThread
{
public:
    Thread();
    void add(int sd);
    void checkNewConnection();

protected:
    void run();
    
private:
    QMutex m_Mutex;
    volatile bool m_Stop;
    QList<int> m_NewConnectionList;
};


Код

Thread::Thread() :
    m_Stop(false)
{
}


void
Thread :: run()
{
    while (!m_Stop)
    {
        checkNewConnection();
        msleep(300);
    }
}

void
Thread :: add(int socketDescriptor)
{
    QMutexLocker lock(&m_Mutex);
    m_NewConnectionList.push_back(socketDescriptor);
}


void
Thread :: checkNewConnection()
{
    QMutexLocker lock(&m_Mutex);
    while (!m_NewConnectionList.isEmpty())
    {
        int socket_descriptor = m_NewConnectionList.takeFirst();
        QSslSocket * sock = new QSslSocket;
        if (!sock->setSocketDescriptor(socket_descriptor)) // связь потеряна, соединения нет или что - то не так
            { qDebug("Fail"); }
        // далее сертификат и ключ и startServerEncryption
    }
}



Если кто знает в чем проблема, пожалуйста объясните...
Заранее благодарен за помощь
PM MAIL   Вверх
SABROG
Дата 30.6.2009, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



И в консоль никаких варнингов не сыпется?


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


Опытный
**


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

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



В общем ситуация в следующем....
1) Сам сокет рабочий остается и  коннект есть, это можно посмотреть, если использовать не ssl соединение
2) Ssl соединение происходит правильно, фукнции установки связи, загрузки сертификата и ключа просходят одинакого, как в родительском, так и в дочернем потоке
Итог: что - то не так с ssl соединением, почему оно не хочет устанавливаться в таких, казалось бы логичных условиях, остается загадкой, надеюсь, что ответ мне дадут на багзилле
Я прикрепил простенький примерчик, того, чего пытаюсь сделать, у кого будет время соберите, гляньте, может я не прав где - то

Это сообщение отредактировал(а) null56 - 1.7.2009, 14:07

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  ssl_problem.tar 20,00 Kb
PM MAIL   Вверх
SABROG
Дата 1.7.2009, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Цитата(null56 @  1.7.2009,  14:06 Найти цитируемый пост)
соберите, гляньте


Чет не собирается

Код

g++ -c -O2 -frtti -fexceptions -mthreads -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT
-DQT_DLL -DQT_NO_DEBUG -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"..\
..\qt-win-opensource-src-4.5.0\include\QtCore" -I"..\..\qt-win-opensource-src-4.
5.0\include\QtNetwork" -I"..\..\qt-win-opensource-src-4.5.0\include" -I"..\..\qt
-win-opensource-src-4.5.0\include\ActiveQt" -I"release" -I"." -I"..\..\qt-win-op
ensource-src-4.5.0\mkspecs\win32-g++" -o release\main.o main.cpp
In file included from main.cpp:2:
tcpsocket.h:8: error: expected class-name before '{' token
tcpsocket.h:15: error: `QAbstractSocket' has not been declared
tcpsocket.h:15: error: `SocketState' has not been declared
tcpsocket.h:15: error: ISO C++ forbids declaration of `socketState' with no type

tcpsocket.h:16: error: `QSslSocket' has not been declared
tcpsocket.h:16: error: `SslMode' has not been declared
tcpsocket.h:16: error: ISO C++ forbids declaration of `mode' with no type
tcpsocket.h:17: error: `QSslError' was not declared in this scope
tcpsocket.h:17: error: template argument 1 is invalid
tcpsocket.h:17: error: ISO C++ forbids declaration of `errors' with no type
tcpsocket.h:19: error: `QAbstractSocket' has not been declared
tcpsocket.h:19: error: `SocketError' has not been declared
tcpsocket.h:19: error: ISO C++ forbids declaration of `err' with no type
main.cpp: In function `int main(int, char**)':
main.cpp:9: error: 'class SslSocket' has no member named 'connectToHostEncrypted
'
mingw32-make[1]: *** [release/main.o] Error 1
mingw32-make[1]: Leaving directory `C:/SABROG/sslSocket/socket_client'
mingw32-make: *** [release] Error 2

C:\SABROG\sslSocket\socket_client>cd ..

C:\SABROG\sslSocket>cd ThreadServer

C:\SABROG\sslSocket\ThreadServer>qmake

C:\SABROG\sslSocket\ThreadServer>mingw32-make release
mingw32-make -f Makefile.Release
mingw32-make[1]: Entering directory `C:/SABROG/sslSocket/ThreadServer'
g++ -c -O2 -frtti -fexceptions -mthreads -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT
-DQT_DLL -DQT_NO_DEBUG -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"..\
..\qt-win-opensource-src-4.5.0\include\QtCore" -I"..\..\qt-win-opensource-src-4.
5.0\include\QtNetwork" -I"..\..\qt-win-opensource-src-4.5.0\include" -I"..\..\qt
-win-opensource-src-4.5.0\include\ActiveQt" -I"release" -I"." -I"..\..\qt-win-op
ensource-src-4.5.0\mkspecs\win32-g++" -o release\main.o main.cpp
In file included from tcpserver.h:5,
                 from main.cpp:2:
thread.h:22: error: ISO C++ forbids declaration of `QSslSocket' with no type
thread.h:22: error: expected `;' before '*' token
In file included from main.cpp:2:
tcpserver.h:15: error: ISO C++ forbids declaration of `QSslSocket' with no type
tcpserver.h:15: error: expected `;' before '*' token
mingw32-make[1]: *** [release/main.o] Error 1
mingw32-make[1]: Leaving directory `C:/SABROG/sslSocket/ThreadServer'
mingw32-make: *** [release] Error 2

---
Похоже у меня Qt собрана с поддержкой OpenSSL... Проверить не могу, сорри..

Это сообщение отредактировал(а) SABROG - 1.7.2009, 14:45


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


Опытный
**


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

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



Блин... тут поэкспериментировали с одним знакомым и он нашел способ при котором работать стало, но я не понимаю, это не совсем логично
Работать стало, если я вызываю одну из функций 
Код

//m_Sock->waitForBytesWritten(1) ;
//m_Sock->waitForReadyRead(1);

после вызова startServerEncryption(), даже на одну миллисекунду и всё отрабатывает
В чем проблема? ведь с функцией waitForEncrypted ничего не работает, а с ними работает
PM MAIL   Вверх
null56
Дата 3.7.2009, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Собственно я догадался в чем проблема и, к сожалению, решить ее нельзя...
QSslSocket дальний родственник QObject и все события, которые происходят с самим сокетом, могут определяться только в EventLoop.
То есть, когда создается новое соединение и я передаю его в тот поток в котором НЕ работает обработчик событий, то объект класса QSslSocket становится мертвым по отношению к событиям, связанным с находящимся внутри объекта сокетом...
Сейчас ставил экспиременты с  обычным незащищенным соединением, и  пытался серверу передать данные от клиента... серверныый сокет молчал на вызовы функций
Код

bytesAvailable();
read();

То есть некому опрашивать сокеты на то или иное событие, а эти функции всего лишь внешний интерфейс, который можно использовать только в качестве анализа уже отработанных exec-ом событий.
Именно поэтому, скорее всего не отрабатывает подтверждение ключа на серверное стороне...
Так что всё завязано в недрах qt
я вижу это так
PM MAIL   Вверх
SABROG
Дата 3.7.2009, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Ничего не понимаю, собрал Qt из репозитория, а прога все-равно не находит QSslSocket.  smile 


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


Опытный
**


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

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



попробуй выкачай qt-creator, целиковый под выньду, у меня работал.... у меня нет винды и я никогда не собирал и не ставил qt под винду
я работаю на gentoo, всё компилируя.... проблем вроде не было
Код

emerge -pv qt-core

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild   R   ] x11-libs/qt-core-4.5.2  USE="glib iconv qt3support ssl -debug -doc -pch" 0 kB

флаг выставлен... остальное сам тянет
PM MAIL   Вверх
SABROG
Дата 6.7.2009, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Собрал таки. Вот такое вижу в консоли:

//ssl_client
Код

onStateChanged: 1
onStateChanged: 2
onStateChanged: 3
onModeChanged 1
onSSlErrors: 1
"The certificate is self-signed, and untrusted"
ENCRYPTED
ON ready read
Data: PREVED CLIENT


//threadServer
Код

New socket: 1760
Valid certificate



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


Опытный
**


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

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



SABROG, в каком случае ты это видишь? когда передается в дочерний поток?
PM MAIL   Вверх
SABROG
Дата 6.7.2009, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Цитата(null56 @ 6.7.2009,  20:44)
SABROG, в каком случае ты это видишь? когда передается в дочерний поток?

На самом деле я просто тупо скомпилил сервер и клиент и запустил оба.


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


Опытный
**


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

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



SABROG, если не сложно... в файле tcpserver.cpp в функции TcpServer :: incomingConnection ( int socketDescriptor ), закомментируй вызов create, а m_SocketThread.add раскомментируй и проверь, будет ли тот же результат... буду благодарен
вот чего тролли написали
Цитата

After you get the incoming QTcpSocket, can you call moveToThread for it and then pass it to the other thread and there in the other thread create a QSslSocket out of it?

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

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

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


 




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


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

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