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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Клиент сервер, Мультитрит, проблемы с чтением  (Прочитано 5641 раз)
bztd
Гость
« : Февраль 03, 2010, 08:45 »

собсно создаю сервер, на каждый коннект создаю новый thread и перемещаю туда сокет ( использую nextPendingConnection) через moveToThread.
мне нужно чтобы поток управлял сим сокетом хитрым образом, поэтому стандартная идей connect exec внутри потока не подойдет. сделал так:
Код:
void Thread::run(){
    qDebug()<<"Thread::run ";
    ...
    while(socket->state()==QAbstractSocket::ConnectedState)
    {
        qDebug()<<"socket may read?"<<socket->state();
        if( this->socket->waitForReadyRead(1000))
       {
            int av=socket->bytesAvailable();
            qDebug()<<"Reading from socket bytes: "<<av;
            QByteArray ara;
            do{
                ara= socket->read(av);
            }while(ara.count()<av);
            qDebug()<<ara;
            QString str(ara);
            qDebug()<<"do addString "<<str;
            if(str.isEmpty()) continue;
            ...
        }
        ...

Собсно проблема в следующем - когда клиентом ( в качве клиента пока юзаю netcat ) передаю третий пакет, то bytesAvailable возвращает его правильную длинну, а при попытке его считать - первый раз возвращается "" при любой следущей попытки чтения с сокета - винда уходит в долгий цыкл, из которого прямой путь в SYGSEGV. do while просто временный костыль, до этого было использование readAll. Собсно циклица именно в вызовах read сокета. Конкретней - в ntdll... Это меня сильно смущает и обескураживает...
Прошу помощи Улыбающийся
Записан
ilyagoo
Гость
« Ответ #1 : Февраль 03, 2010, 10:09 »

Цитировать
мне нужно чтобы поток управлял сим сокетом хитрым образом

каким хитрым? чем не нравится
Код:
void Thread::run()
{
    QTcpSocket socket;
    connect( &socket, SIGNAL( readyRead() ), this, SLOT( OnReadyRead() ), Qt::QueuedConnection );
    exec()
}
?
Записан
bztd
Гость
« Ответ #2 : Февраль 03, 2010, 10:29 »

Собсно каким именно хитрым, поясню.. в случае с connect exec прийдется делать disconnect =) вот это то мне и не нравится. получается что у QT поток не совсем поток...
Записан
BRE
Гость
« Ответ #3 : Февраль 03, 2010, 10:33 »

Собсно каким именно хитрым, поясню.. в случае с connect exec прийдется делать disconnect =) вот это то мне и не нравится. получается что у QT поток не совсем поток...
Что значит придется делать disconnect? Дисконнект чего сигналов или дисконнект соединения? Какие трудности это вызывает?
У Qt нет своих потоков, он использует механизм потоков платформы.
« Последнее редактирование: Февраль 03, 2010, 10:35 от BRE » Записан
maxxant
Гость
« Ответ #4 : Февраль 03, 2010, 10:35 »

Код:
            QByteArray ara;
            do{
                ara= socket->read(av);
            }while(ara.count()<av);
            qDebug()<<ara;
        ...

наверное хотелось так:
Код:
        ...
                ara += socket->read(av);
        ...
Записан
bztd
Гость
« Ответ #5 : Февраль 03, 2010, 10:45 »

я хочу чтобы кроме этого потока еще один поток мог использовать сокет через socketDescriptor. если я соединю кготовность чтения с обработчиком, то второй поток уже не сможет читать и прийдется делать дисконнект с чтения. однако в случае с другой платформой, я бы просто согласовал потоки. по старинке.. собсно мне интересно знать почему я не могу сделать это тут.
Записан
maxxant
Гость
« Ответ #6 : Февраль 03, 2010, 11:02 »

я хочу чтобы кроме этого потока еще один поток мог использовать сокет через socketDescriptor. если я соединю кготовность чтения с обработчиком, то второй поток уже не сможет читать и прийдется делать дисконнект с чтения. однако в случае с другой платформой, я бы просто согласовал потоки. по старинке.. собсно мне интересно знать почему я не могу сделать это тут.

bool QAbstractSocket::setSocketDescriptor ( int socketDescriptor, SocketState socketState = ConnectedState, OpenMode openMode = ReadWrite )

Initializes QAbstractSocket with the native socket descriptor socketDescriptor. Returns true if socketDescriptor is accepted as a valid socket descriptor; otherwise returns false. The socket is opened in the mode specified by openMode, and enters the socket state specified by socketState.

Note: It is not possible to initialize two abstract sockets with the same native socket descriptor.
Записан
bztd
Гость
« Ответ #7 : Февраль 03, 2010, 11:05 »


наверное хотелось так:
Код:
        ...
                ara += socket->read(av);
        ...
Спасибо за исправление, именно так, однако проблемы это не решает.  Всмысле той с зависанием и нарушением сегментации. внутри read происходит оно.. и я даже без идей почему
Записан
ilyagoo
Гость
« Ответ #8 : Февраль 03, 2010, 11:28 »

а в каком потоке находится сокет? ты его случайно не так сделал QTcpSocket( this )?
больше кода:)
Записан
maxxant
Гость
« Ответ #9 : Февраль 03, 2010, 11:41 »

Спасибо за исправление, именно так, однако проблемы это не решает.  Всмысле той с зависанием и нарушением сегментации. внутри read происходит оно.. и я даже без идей почему

QObject Reentrancy

QObject is reentrant. Most of its non-GUI subclasses, such as QTimer, QTcpSocket, QUdpSocket, QHttp, QFtp, and QProcess, are also reentrant, making it possible to use these classes from multiple threads simultaneously. Note that these classes are designed to be created and used from within a single thread; creating an object in one thread and calling its functions from another thread is not guaranteed to work.

Мысль только одна: проблема с потоками. Пробуйте написать сначала попроще, типа как примерах.
Записан
bztd
Гость
« Ответ #10 : Февраль 03, 2010, 13:17 »

Спасибо, буду думать, искать.
 
Насчет потоков, сокету было сделано setParent(0), moveToThread(this);
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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