crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> Обрыв соединения QTcpSocket
OrSOn
  опции профиля:
сообщение 16.2.2010, 14:47
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 46
Регистрация: 8.12.2009
Пользователь №: 1289

Спасибо сказали: 0 раз(а)




Репутация:   0  


Всем добрый день! Столкнулся с довольно неприятной проблемой при работе с сокетами... Суть проблемы в следующем:

Имеется сервер и клиент, для общения используют сокеты. В некий момент времени клиент рушится (ну или связь падает, не суть важно), при этом сервер пытается что-то писать в сокет, что приводит к ошибке. Чтобы избежать этого, пробовал ввести проверку

if( tcpSocket->state() != 3 )
    return;
tcpSocket->flush();


Так вот случаются ситуации, что проверка состояния проходит, а сразу после нее до начала проталкивания информации клиент падает и на tcpSocket->flush() снова вылетаю с ошибкой.

Если кто сталкивался с подобным, подскажите, пожалуйста, как это можно обойти...

Сообщение отредактировал OrSOn - 16.2.2010, 14:48
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
OrSOn
  опции профиля:
сообщение 19.2.2010, 12:15
Сообщение #2


Студент
*

Группа: Участник
Сообщений: 46
Регистрация: 8.12.2009
Пользователь №: 1289

Спасибо сказали: 0 раз(а)




Репутация:   0  


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

Раскрывающийся текст

Объявление класса

#ifndef NTHREAD_H
#define NTHREAD_H

#include <QThread>
#include <QTcpSocket>
#include <QTimer>


struct PrioritySocket {
    QTcpSocket * tSocket;
    int prior;
};

struct HashStruct {
    QByteArray hashArr;
    QString filePath;
};

class NThread : public QThread
{
    Q_OBJECT

public:
    NThread( int num );

    void run();
    void readBD(QString & DBName,QString & DBHost, QString & DBUser,QString &  DBPassword,QString & DBDriver);
    bool isFree();
    void unlockDB( QString bName );
    void setIsFree( bool isFree );
    void stopCurrentWork();
    void updateHashMap();
    int myNum;

signals:
    void error(QTcpSocket::SocketError socketError);
    void needDB( QString bName, int threadName );
    void endThreadSocket( PrioritySocket *pSocket );
    void unlockBase( QString bName );
    void readF();

private:
    QMap<QString, HashStruct> hashMap;
    QString neededDB;
    bool dbLocked;
    QTcpSocket *tcpSocket;
    int socketDescriptor;
    QString text;
    bool HasBD;
    int CountFile;
    QString KARTADRIVER;
    QString KARTAHOST;
    QString KARTAGISDATA;
    QString KARTALISTS;
    quint32 blockSize;
    bool threadEnd;
    bool freeThread;
    PrioritySocket *priorSocket;
    bool setSocketFlag;

    int blockLength;

    void setThreadSocketFn();

public slots:
    void readFortune();
    void endThread();
    void setThreadSocket( PrioritySocket *pSocket );
    void setIsFree();
};

#endif


конструктор
NThread::NThread( int num )
: QThread(0)
{
                  myNum = num;
    moveToThread( this );
    setBaseValues();

}


Run
void NThread::run()
{
    connect( this, SIGNAL( readF() ), this, SLOT( readFortune() ), Qt::QueuedConnection );
    exec();
}


Функция установки текущего рабочего сокета на поток (сокет создается в основном потоке и передается на обратоку в один из потоков)
void NThread::setThreadSocket( PrioritySocket *pSocket )
{
    priorSocket = pSocket;    
    tcpSocket = priorSocket->tSocket;

    connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(setIsFree()), Qt::DirectConnection);

    emit readF();
    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readFortune()), Qt::QueuedConnection);
}


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

void NThread::setIsFree()
{
    disconnect(tcpSocket, SIGNAL(disconnected()), this, SLOT(setIsFree()));
    priorSocket->prior = -1;
    emit endThreadSocket( priorSocket ); //Сигнал основному потоку, что данный сокет завершил текущую работу, удалить, если связь прервалась или поставить в очередь, если есть еще запросы с него.
    freeThread = true;
    
}



Вот примерно такая структура...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме
- OrSOn   Обрыв соединения QTcpSocket   16.2.2010, 14:47
- - sploid   так в чем проблема? в том что сервер не знает запи...   16.2.2010, 17:29
- - SABROG   Цитата(OrSOn @ 16.2.2010, 14:47) вылетаю ...   16.2.2010, 20:28
- - OrSOn   Обработать ошибку нельзя - полностью прерывается д...   17.2.2010, 10:07
|- - BRE   Цитата(OrSOn @ 17.2.2010, 10:07) Обработа...   17.2.2010, 10:15
- - OrSOn   while( tmpLength < file.size() ...   17.2.2010, 10:19
- - BRE   Покажи как создается объект tcpSocket и какие сигн...   17.2.2010, 10:25
- - OrSOn   Значит по порядку... Объект создается нормально, н...   17.2.2010, 10:34
- - BRE   Класс TcpSocket данные кеширует сам и отправляет и...   17.2.2010, 10:50
- - OrSOn   Увы, но удаления объекта не происходит. Я уже дума...   17.2.2010, 11:02
- - BRE   Ну так если ты хочешь отправлять синхронно, то поп...   17.2.2010, 11:39
- - OrSOn   Боюсь, что так будет не лучше, ибо сложнее отследи...   17.2.2010, 11:45
- - BRE   Как только ты записал последний кусок данных в сок...   17.2.2010, 12:11
- - OrSOn   Попробовал, ничего не вышло... Вот код: while...   17.2.2010, 14:50
|- - BRE   Набросал небольшой пример (клиент/сервер) для пере...   17.2.2010, 16:29
- - OrSOn   Спасибо, сейчас гляну Что-то я не совсем понял......   17.2.2010, 17:12
|- - BRE   Цитата(OrSOn @ 17.2.2010, 17:12) int writ...   17.2.2010, 17:23
- - OrSOn   Попробовал, но, увы, этот вариант врядли прокатит(...   18.2.2010, 13:15
|- - BRE   Цитата(OrSOn @ 18.2.2010, 13:15) Получает...   18.2.2010, 14:33
- - OrSOn   ну не знаю, я запускал в дебаге твой пример, так т...   18.2.2010, 14:35
|- - BRE   Цитата(OrSOn @ 18.2.2010, 14:35) ну не зн...   18.2.2010, 18:53
- - OrSOn   Да, что-то я тоже не заметил, спасибо, так работае...   19.2.2010, 11:50
- - BRE   Покажи подробно (закопипасть сюда) класс этого пот...   19.2.2010, 11:59
- - OrSOn   Ну все будет сложно сюда перенести, ибо много, я к...   19.2.2010, 12:15
- - SABROG   connect( this, SIGNAL( readF() ...   19.2.2010, 12:25
- - OrSOn   Сокет принадлежит главному потоку, объект NThread ...   19.2.2010, 12:31
- - SABROG   Это не правильно. Соединение не должно быть прямым...   19.2.2010, 13:01
- - OrSOn   У меня и так эта проверка стоит, согласен, можно у...   19.2.2010, 13:02
- - BRE   Сокет принадлежит главному потоку, а должен принад...   19.2.2010, 13:12
- - SABROG   Смотри что получается. Сокет находится в гуишном п...   19.2.2010, 13:19
- - OrSOn   Изначально так и планировалось, чтобы на 1 запрос ...   19.2.2010, 13:26
- - SABROG   Задача потока выполнять долгую операцию на фоне по...   19.2.2010, 13:45
- - OrSOn   Вот я и думал об этом как раз, чтобы обрабатывающи...   19.2.2010, 13:48
- - BRE   OrSOn, я скоро приеду домой и сброшу тебе пример а...   19.2.2010, 14:03
- - OrSOn   Ок, спасибо, буду ждать)   19.2.2010, 14:05
- - SABROG   Думаю вместо того, чтобы данные передавать с сигна...   19.2.2010, 14:37
|- - BRE   Цитата(SABROG @ 19.2.2010, 14:37) Думаю в...   19.2.2010, 15:06
- - SABROG   Цитата(BRE @ 19.2.2010, 15:06) А если при...   19.2.2010, 16:19
|- - BRE   Цитата(SABROG @ 19.2.2010, 16:19) В общем...   19.2.2010, 16:53
- - OrSOn   Спасибо, сейчас буду пробовать все посоветованное....   24.2.2010, 10:30
- - OrSOn   А такой вопрос еще... А можно ли рассматривать как...   24.2.2010, 16:10
- - SABROG   Цитата(OrSOn @ 24.2.2010, 16:10) а затем ...   25.2.2010, 2:43
- - OrSOn   А почему это я не смогу вернуть их в главный поток...   25.2.2010, 9:47
- - BRE   Пока я вижу один момент с перетягиванием объектов ...   25.2.2010, 12:14
- - OrSOn   Увы, при перемещении я не могу рвать коннект, в то...   25.2.2010, 12:44


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


7 чел. читают эту тему (гостей: 7, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 2.3.2025, 12:54