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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Передача сообщений между клиентом и сервером  (Прочитано 5279 раз)
Edynchik
Гость
« : Декабрь 24, 2010, 16:32 »

Помогите разобраться, для примера клиент-серверного приложения использовал FortuneClient и FortuneServer. Там после передачи сообщения используется disconnectFromHost. То есть соединение клиента с сервером разрывается, и собственно вопрос: Возможно ли обмен сообщениями между клиентом и сервером и обратно,без постоянного разрыва соединения? И собственно как это сделать?
Клиент:
Код:
void MainWindow::readFortune()
{
//! [9]
    QDataStream in(tcpSocket);
    in.setVersion(QDataStream::Qt_4_7);

    if (blockSize == 0) {
        if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))
            return;
//! [8]

//! [10]
        in >> blockSize;
    }

    if (tcpSocket->bytesAvailable() < blockSize)
        return;
//! [10] //! [11]

    QString nextFortune;
    in >> nextFortune;

    if (nextFortune == currentFortune) {
        QTimer::singleShot(0, this, SLOT(requestNewFortune()));
        return;
    }
//! [11]

//! [12]
    currentFortune = nextFortune;
//! [9]
    //ui->lineEdit->setText(currentFortune);
    ui->textEdit->setText(currentFortune);
    ui->pushButton->setEnabled(true);
}
Сервер:
Код:
void MainWindow::on_Button1_clicked()
{
        m_ptcpServer = new QTcpServer(this);
        if (!m_ptcpServer->listen(QHostAddress(ui->lineEdit_2->text()) , ui->lineEdit_3->text().toInt()))
            {
            ui->label_3->setText("Server is not working " + m_ptcpServer->errorString());
            m_ptcpServer->close();
            return;
            }
        ui->label_3->setText("Server is working");
        connect(m_ptcpServer, SIGNAL(newConnection()),this,SLOT(slotNewConnection()));

}

void MainWindow::slotNewConnection()
{

        //QTcpSocket* pClientSocket = m_ptcpServer->nextPendingConnection();
        pClientSocket = new QTcpSocket(this);
        pClientSocket = m_ptcpServer->nextPendingConnection();
        connect(pClientSocket, SIGNAL(disconnected()),
                        pClientSocket, SLOT(deleteLater())
                   );
        connect(pClientSocket, SIGNAL(readyRead()),
                        this,   SLOT(slotReadClient())
                   );
        ui->label_3->setText("Server Response: Connected!");
        //sendToClient(pClientSocket, "Server Response: Connected!");
        //sendMessage("Server Response: Connected!");


}


void MainWindow::on_pushButton_2_clicked()
{
    //m_ptcpServer = new QTcpServer(this);
    //FileServer SERVER1("C:/",this);
    //QTcpSocket* pClientSocket = (QTcpSocket*)sender();
    sendMessage(ui->lineEdit->text());
    //SERVER1.incomingConnection(m_ptcpServer->socketDescriptor());
    ;
}


void MainWindow::sendMessage(QString MESSAGE)
{

    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_7);

    out << (quint16)0;
    //out << fortunes.at(qrand() % fortunes.size());
    //out << ui->lineEdit->text();
    out << MESSAGE;
    out.device()->seek(0);
    out << (quint16)(block.size() - sizeof(quint16));


    /*QTcpSocket *pClientSocket = m_ptcpServer->nextPendingConnection();//tcpServer->nextPendingConnection();
    connect(pClientSocket, SIGNAL(disconnected()),
            pClientSocket, SLOT(deleteLater()));*/

    pClientSocket->write(block);
    pClientSocket->disconnectFromHost();
    //clientConnection->write(block);
    //clientConnection->disconnectFromHost();

}
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #1 : Декабрь 24, 2010, 16:36 »

Цитировать
Возможно ли обмен сообщениями между клиентом и сервером и обратно,без постоянного разрыва соединения?
Да, возможен.
Цитировать
И собственно как это сделать?
Не разрывать соединение.
Записан

ArchLinux x86_64 / Win10 64 bit
Edynchik
Гость
« Ответ #2 : Декабрь 24, 2010, 16:48 »

Не разрывать соединение.
Да это было наиболее очевидное решение, убрав disconnectFromHost,при отправке первого сообщения от сервера к клиенту все нормально,а вот при отправке второго сообщения оно приходит пустым, т.е. в строчке in >> nextFortune; пусто (""). И собственно на этом все заканчивается.
Записан
brankovic
Гость
« Ответ #3 : Декабрь 24, 2010, 16:49 »

Разрыв соединения гарантирует, что данные отправлены. Если не разрывать, то надо вызывать QSocket::flush после каждого сообщения.
Записан
Edynchik
Гость
« Ответ #4 : Декабрь 24, 2010, 17:06 »

Разрыв соединения гарантирует, что данные отправлены. Если не разрывать, то надо вызывать QSocket::flush после каждого сообщения.
Добавление flush после отправки сообщения не помогла.
Код:
pClientSocket->write(block);
pClientSocket->flush();
но отметиласть интересная особенность: первое сообщение принимается нормально,второе и третье нет, а четверное-нормально, и так далее через два...
Записан
JamS007
Гость
« Ответ #5 : Декабрь 24, 2010, 17:40 »

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

И еще, иногда бывает, что по ошибке ставят на сервере quint16 blockSize а на клиенте quint32 blockSize, или наоборот. При первом сообщении все тоже будет нормально, а с последующими будет беда.
Записан
brankovic
Гость
« Ответ #6 : Декабрь 25, 2010, 11:48 »

block_size не присваивается 0. И вообще это пример с дисконнектом, выкладывать надо ваш, который не работает.
« Последнее редактирование: Декабрь 25, 2010, 11:55 от brankovic » Записан
Edynchik
Гость
« Ответ #7 : Декабрь 25, 2010, 14:21 »

4 brankovic
а где именно надо присваивать block_size=0?
Сосбственно вот два проекта,клиента и сервера...
« Последнее редактирование: Декабрь 26, 2010, 00:01 от Edynchik » Записан
Edynchik
Гость
« Ответ #8 : Декабрь 27, 2010, 09:29 »

А ларчик то просто открывался: достаточтно убрать out << (quint16)(block.size() - sizeof(quint16)); и поставаить pClientSocket->flush();и все работает)))
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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