Russian Qt Forum

Qt => Работа с сетью => Тема начата: fuCtor от Май 16, 2010, 12:31



Название: Не могу понять поведение сокета
Отправлено: 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();
/*
...
*/

}


Название: Re: Не могу понять поведение сокета
Отправлено: garryHotDog от Май 16, 2010, 17:12
попробуй отследить полное поведение клиента с помощью
Цитировать
void QAbstractSocket::stateChanged ( QAbstractSocket::SocketState socketState )   [signal]
посмотри почему он закрывается


Название: Re: Не могу понять поведение сокета
Отправлено: fuCtor от Май 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 передаются.


Название: Re: Не могу понять поведение сокета
Отправлено: garryHotDog от Май 16, 2010, 20:59
У меня похожая проблема в консольном приложении, но в консоли сразу же вылазило предупреждение....насколько я понял ты не можешь использовать сокет в другом потоке...решил проблему с m_Socket.moveToThread(this) в конструкторе потока.


Название: Re: Не могу понять поведение сокета
Отправлено: ритт от Май 17, 2010, 06:11
ом...многопоточный сервер на конкуренте? незачёт


Название: Re: Не могу понять поведение сокета
Отправлено: fuCtor от Май 17, 2010, 07:06
ом...многопоточный сервер на конкуренте? незачёт

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

Тогда лучше делать некоторый набор потоков и хранилище сокетов. При подключении закидывать новый дескриптор сокета в это хранилище, а потом потоками из выбирать на обработку по очереди. В основной нити объекты QTcpSocket не создаются, а создаются во вспомогательных.
(http://s3.amazonaws.com/floomby/5_17_2010/A4dml0Mx9E7rnNlSTExTA.jpg)
Как то так. Ход мыслей верный? Или снова не туда убрел :)


Название: Re: Не могу понять поведение сокета
Отправлено: ритт от Май 17, 2010, 08:39
если задача однообразна (тело потока), QThreadPool в руки - наиболее простой/удобный способ


Название: Re: Не могу понять поведение сокета
Отправлено: garryHotDog от Май 17, 2010, 11:49
посмотри в ассисте пример многопоточного сервака


Название: Re: Не могу понять поведение сокета
Отправлено: fuCtor от Май 17, 2010, 13:25
если задача однообразна (тело потока), QThreadPool в руки - наиболее простой/удобный способ

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

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

Видел его.


Название: Re: Не могу понять поведение сокета
Отправлено: andrew.k от Октябрь 26, 2010, 17:35
ом...многопоточный сервер на конкуренте? незачёт

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