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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Не могу понять поведение сокета  (Прочитано 6399 раз)
fuCtor
Гость
« : Май 16, 2010, 12:31 »

Пишу службу, которая будет слушать порт, принимать подключения и считывать передаваемые данные. Но возникла проблема. Клиент подключается без проблем, эмитится сигнал что есть данные. В слоте следую двумя путями:
1. (первоначальный) Начинаю вычитывать и писать все куда надо.
2. (текущий) Помещаю через run в QThreadPool, для многопоточной обработки.

НО в обоих случаях непонятное поведение (в документации не нашел объяснения). После выхода из слота сокет закрывается, как результат при первом пути не все данные считываются, при втором в поток попадает уже закрытый сокет, а так как при дисконекте самоуничтожение, то и удаленный объект.

Что делаю не так?

Ну и собственно код:
Код
C++ (Qt)
typedef QPointer<QTcpSocket> QTcpSocketPtr;
 
void Server::incomingConnection( int socketDescriptor )
{
QTcpSocket * socket = new QTcpSocket();
socket->setSocketDescriptor(socketDescriptor);
 
qDebug() << "New connection #" << socketDescriptor;
 
connect(socket, SIGNAL(readyRead()),
this, SLOT(readyRead()));
connect(socket, SIGNAL(readyRead()),
socket, SLOT(deleteLater()));
}
 
void Server::readyRead()
{
QTcpSocket * socket = qobject_cast<QTcpSocket *>(sender());
QTcpSocketPtr * socket_ptr = new QTcpSocketPtr(socket) ;
QtConcurrent::run(&Server::serviceConnection, socket_ptr, this);
 
}
 
void Server::serviceConnection( QTcpSocketPtr * socketPtr, Server* th )
{
QTcpSocket * socket = socketPtr->data();
/*
...
*/

}
Записан
garryHotDog
Гость
« Ответ #1 : Май 16, 2010, 17:12 »

попробуй отследить полное поведение клиента с помощью
Цитировать
void QAbstractSocket::stateChanged ( QAbstractSocket::SocketState socketState )   [signal]
посмотри почему он закрывается
Записан
fuCtor
Гость
« Ответ #2 : Май 16, 2010, 17:58 »

В документации нашел:
Цитировать
Event driven objects may only be used in a single thread. Specifically, this applies to the timer mechanism and the network module. For example, you cannot start a timer or connect a socket in a thread that is not the object's thread.

Случаем не значит ли это что я не могу использовать сокет из одного потока в другом?

upd: посмотрел стек вызовов. Такое ощущение что разрыв по таймауту идет, либо еще по чему, не могу понять, но после первого пакета связь рвется (на стороне клиента). Данные по GPRS передаются.
« Последнее редактирование: Май 16, 2010, 18:18 от fuCtor » Записан
garryHotDog
Гость
« Ответ #3 : Май 16, 2010, 20:59 »

У меня похожая проблема в консольном приложении, но в консоли сразу же вылазило предупреждение....насколько я понял ты не можешь использовать сокет в другом потоке...решил проблему с m_Socket.moveToThread(this) в конструкторе потока.
Записан
ритт
Гость
« Ответ #4 : Май 17, 2010, 06:11 »

ом...многопоточный сервер на конкуренте? незачёт
Записан
fuCtor
Гость
« Ответ #5 : Май 17, 2010, 07:06 »

ом...многопоточный сервер на конкуренте? незачёт

Да уже понял ) буду переделывать, просто логически так хорошо укладывалось, но на практике не вышло.

Тогда лучше делать некоторый набор потоков и хранилище сокетов. При подключении закидывать новый дескриптор сокета в это хранилище, а потом потоками из выбирать на обработку по очереди. В основной нити объекты QTcpSocket не создаются, а создаются во вспомогательных.

Как то так. Ход мыслей верный? Или снова не туда убрел Улыбающийся
Записан
ритт
Гость
« Ответ #6 : Май 17, 2010, 08:39 »

если задача однообразна (тело потока), QThreadPool в руки - наиболее простой/удобный способ
Записан
garryHotDog
Гость
« Ответ #7 : Май 17, 2010, 11:49 »

посмотри в ассисте пример многопоточного сервака
Записан
fuCtor
Гость
« Ответ #8 : Май 17, 2010, 13:25 »

если задача однообразна (тело потока), QThreadPool в руки - наиболее простой/удобный способ

Да однообразны, именно пул и думал использовать.
Но железка (дистанционный мониторинг) дурная на другом конце, не получается в асинхроне с ней работать (после чтения происходит разрыв принудительный, не понятно кто обрывает) в синхронном все норм, а один сеанс длится порядка 2-3 сек. Эт сколько же потоков надо будет, эх =)

посмотри в ассисте пример многопоточного сервака

Видел его.
Записан
andrew.k
Гость
« Ответ #9 : Октябрь 26, 2010, 17:35 »

ом...многопоточный сервер на конкуренте? незачёт

объясните почему незачет?
Сейчас тоже делаю сервер. Для каждого входящего подключения. отдельный поток с сокетом. Чем это плохо?
Соединений должно быть не много. Десятки с лучшем случае, не тыщи.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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