Russian Qt Forum

Qt => Работа с сетью => Тема начата: demiurg от Май 08, 2011, 20:32



Название: Ошибка при отключении клиента
Отправлено: demiurg от Май 08, 2011, 20:32
Пишу сервер на сокетах , ввёл вывод ошибки в консоль.
При отключении каждого клиента выводит пустую ошибку , в дебагере тоже пустая.
Код:
bool EchoServer::start() {

    if ( !listen(QHostAddress::Any, 5678) ) {
        cout << STR(QObject::tr("Не могу запустить сервер: %1\n")
                   .arg( errorString() )+0x0d+0x0a );

        return false;
         }
    connect(this, SIGNAL(newConnection()), this, SLOT(addConnection()));
    cout << STR(QObject::tr("Сервер запущен\n")+0x0d+0x0a);
    return true;
}

void EchoServer::addConnection()
{

    QTcpSocket *client = nextPendingConnection();
    connect(client, SIGNAL(disconnected()),
            this, SLOT(removeConnection()));
    connect(client, SIGNAL(readyRead()), this,  SLOT(onRead()));
    connect(client, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(displayError(QAbstractSocket::SocketError)));


Код:
void EchoServer::removeConnection(){
    QTcpSocket *client = qobject_cast<QTcpSocket*>(sender());
    QHostAddress addr = client->peerAddress();
    cout << STR(QObject::tr("Клиент %1 отключен\n")
                         .arg( addr.toString() )+0x0d+0x0a);
    m_clients.removeAt(m_clients.indexOf(client));
    client->deleteLater();
}

Код:
void EchoServer::displayError(QAbstractSocket::SocketError)
{
    cout << STR(QObject::tr("\nОшибка %1\n").arg(errorString()));
}

Как проверить отчего она возникает? на запрос serverError возвращает -1 - An unidentified error occurred.


Название: Re: Ошибка при отключении клиента
Отправлено: LisandreL от Май 09, 2011, 02:46
Сигнал error() получаете от сокета, а errorString() в displayError берёте от сервера. Надо как и в removeConnection кастовать sender и выводить client->errorString().

Ну и кроме того:
1) Скастованное qobject_cast значение лучше всегда проверять на ноль.
2) Вместо removeAt+indexOf можно использовать removeOne
3) peerAddress() при отключённом сокете должен возвращать всегда QHostAddress::Null


Название: Re: Ошибка при отключении клиента
Отправлено: demiurg от Май 09, 2011, 11:48
Мда ступил с ошибкой. Но  проблема не решилась только теперь она приобрела название The remote host closed the connection.  Собственно почему это ошибка? Вводил условия на проверку NULL для каста и QHostAddress  - все определяется, адрес позвращает не NULL. Но в слоте removeConnection()  состояние сокета определяется как QAbstractSocket::UnconnectedState. Я в этот момент не вьехал. Почему ошибка? И возникает она где до вызова слота removeConnection() .
Вообще то всё работает, но вот эта ошибка просто мозолит глаза, да и не очень уверен что отключение проходит корректно.


Название: Re: Ошибка при отключении клиента
Отправлено: merke от Май 09, 2011, 11:57
При отключении всегда генерится ошибка. И сначала срабатывает сигнал ошибки, а уже потом сигнал отключения.


Название: Re: Ошибка при отключении клиента
Отправлено: demiurg от Май 09, 2011, 12:32
ААААА  Нюансы аднака ;D

Поставил условие
 if (client->error()!=1)
    {
    cout << STR(QObject::tr("\nОшибка %1\n").arg(client->errorString()));
    };

А ещё такой нубский вопрос : как мне связать событие закрытия окна консоли и деструктор сервера  ?

Код:
EchoServer::~EchoServer() {
///обработка
}