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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: НЕ доходят сообщения с сервера  (Прочитано 10922 раз)
Max Payne
Гость
« : Январь 03, 2011, 16:31 »

Здравствуйте, мне нужна помощь, излагаю суть:
Есть сервер который отсылает текст клиенту по запросу, но если текстовый файл большой то до клиента не доходит то что отправляет сервер... Привожу код:
Сервер:
Код:
QFile as (n_key);
            if (!as.open(QIODevice::ReadOnly|QIODevice::Text))
            {
                text_w = "ERROR";

            }
            else
            {
                QDataStream in(&as);
                QString ner, bnm,str,str2;
                int loh;
                in >> str >> str2>>text_w>>loh >>bnm;
                qDebug () << "\n\n ++++++++++++++\n\n " << str.size() << "   *  " << str2.size();
            }
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_4_0);
        out << (quint16)0;
        qDebug () << "Size array " << text_w.size();
        out << text_w;
        qDebug()<< "OUT text_w"<< text_w;
        out.device()->seek(0);
        out << (quint16)(block.size() - sizeof(quint16));
        int r = tcpSocket.write(block,block.size());

        QString errr = tcpSocket.errorString();
        qDebug() << " ERroro : " << errr << "  int write  " << r;
        tcpSocket.waitForBytesWritten();
        tcpSocket.flush();
        tcpSocket.disconnectFromHost();
        tcpSocket.waitForDisconnected();
Во-первых у меня tcpSocket.write возвращает записаные байты размер блока * 2 +6 байт... Почему так?
Во-вторых если размер файла не большой то он нормально доходит и отображается.
Клиент :
Код:
QDataStream in(tcpSocket);
     in.setVersion(QDataStream::Qt_4_0);
    if (blockSize == 0)
     {
         if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))
             return;
         in >> blockSize;
     }

     if (tcpSocket->bytesAvailable() < blockSize)
         return;
        qDebug() << "Size" << blockSize <<  " av "  << tcpSocket->bytesAvailable() ;
             tcpSocket->waitForReadyRead();
            //receive_text = tcpSocket->readAll();
            in >> receive_text;
            qDebug()<< "\n\n " << receive_text.size();
            if (receive_text != "ERROR")
            {
                emit send_text(receive_text);
                tcpSocket->flush();
                tcpSocket->waitForDisconnected();
            }
        }

В поток нельзя писать больше 64 кб ? Надо разбивать На куски?
Как разбить QString на куски определенного  размера? QString::split не вариант так как текст может быть кто знает какой, и чем разбивать можно только догадываться... ЗАранее спасибо за помощь...
Записан
merke
Гость
« Ответ #1 : Январь 04, 2011, 11:32 »

Привожу вам пример клиент-серверного приложения:

Клиент подключается к серверу, при удачном коннекте клиент шлет на сервер файл. Сервер принимает файл и сохраняет его на диск.

серверная часть:

mainwindow.h

Код
C++ (Qt)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#include <QDataStream>
#include <QFile>
#include <QDir>
 
namespace Ui {
   class MainWindow;
}
 
class MainWindow : public QMainWindow {
   Q_OBJECT
public:
   MainWindow(QWidget *parent = 0);
   ~MainWindow();
 
protected:
   void changeEvent(QEvent *e);
 
private:
   Ui::MainWindow *ui;
   QTcpServer *pServer;
   QTcpSocket *pSocket;
   quint64 nextBlockSize;
 
private slots:
   void newConnection();
   void pSocketReadyRead();
};
 
#endif // MAINWINDOW_H

mainwindow.cpp

Код
C++ (Qt)
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent) :
       QMainWindow(parent),
       ui(new Ui::MainWindow)
{
   ui->setupUi(this);
   pServer = new QTcpServer(this);
   pSocket = new QTcpSocket(this);
   pServer->listen(QHostAddress::Any, 1234);
   connect(pServer, SIGNAL(newConnection()), this, SLOT(newConnection()));
}
 
void MainWindow::newConnection()
{
   QTcpSocket *pSocket = pServer->nextPendingConnection();
   connect (pSocket, SIGNAL(disconnected()), pSocket, SLOT(deleteLater()));
   connect (pSocket, SIGNAL(readyRead()), this, SLOT(pSocketReadyRead()));
   nextBlockSize = 0;
}
 
void MainWindow::pSocketReadyRead()
{
   QTcpSocket * socket = static_cast<QTcpSocket*>(sender());
 
   forever
   {
       QDataStream stream(socket);
       stream.setVersion(QDataStream::Qt_4_7);
 
       if (nextBlockSize == 0)
       {
           if (socket->bytesAvailable() < sizeof(quint64))
               return;
           stream >> nextBlockSize;
       }
       if (nextBlockSize > socket->bytesAvailable())
           return;
 
       QByteArray arrFile;
 
       stream >> arrFile;
       QFile file("C:\\rec.jpg");
       file.open(QIODevice::WriteOnly);
       file.write(arrFile);
 
       nextBlockSize = 0;
   }
}
 
 
 
MainWindow::~MainWindow()
{
   delete ui;
}
 
void MainWindow::changeEvent(QEvent *e)
{
   QMainWindow::changeEvent(e);
   switch (e->type()) {
   case QEvent::LanguageChange:
       ui->retranslateUi(this);
       break;
   default:
       break;
   }
}


клиентская часть:

mainwindow.h
Код
C++ (Qt)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include <QTcpSocket>
#include <QHostAddress>
#include <QDataStream>
#include <QFile>
#include <QDir>
 
 
namespace Ui {
   class MainWindow;
}
 
class MainWindow : public QMainWindow
{
   Q_OBJECT
 
public:
   explicit MainWindow(QWidget *parent = 0);
   ~MainWindow();
 
private:
   Ui::MainWindow *ui;
   QTcpSocket *pSocket;
 
private slots:
   void on_pushButton_clicked();
   void onConnected();
};
 
#endif // MAINWINDOW_H

mainwindow.cpp

Код
C++ (Qt)
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);
   pSocket = new QTcpSocket(this);
   connect(pSocket, SIGNAL(connected()), this, SLOT(onConnected()));
}
 
void MainWindow::onConnected()
{
   QByteArray block;
   QDataStream stream(&block, QIODevice::WriteOnly);
   stream.setVersion(QDataStream::Qt_4_7);
   QFile file("C:\\test.jpg");
   file.open(QIODevice::ReadOnly);
   QByteArray buf = file.readAll();
   stream << quint64(file.size());
   stream << buf;
   pSocket->write(block);
   pSocket->flush();
}
 
MainWindow::~MainWindow()
{
   delete ui;
}
 
void MainWindow::on_pushButton_clicked()
{
   pSocket->connectToHost(QHostAddress::LocalHost, 1234);
}


Записан
Madgeniy
Гость
« Ответ #2 : Февраль 13, 2011, 22:56 »

У меня немного другая проблема. Отсылаю сообщение с клиента на сервер и обратно.
Проблема пока в клиенте. Иногда приходят все сообщения, иногда ни одного, иногда несколько приходит.
Такое ощущение, что flush не срабатывает, потому что слишком быстро происходит отправка.

Код принятия сообщения на сервере:

Код:
void Compressor::slotReadClient()
{
    QTcpSocket * socket = static_cast<QTcpSocket*>(sender());
    QString str;
    QByteArray array;
    QStringList strings;
    QDataStream in(socket);
    in.setVersion(12);
    for (;;) {
        if (!blockSize) {
            if (socket->bytesAvailable() < sizeof(quint16)) {
                break;
            }
            in >> blockSize;
        }

        if (socket->bytesAvailable() < blockSize) {
            break;
        }
        in >> str;
        blockSize = 0;
    }

    //парсинг str
    strings = str.split("#");
...
}

Код отправки сообщения с клиента:

Код:
    QByteArray  arrBlock;
    QDataStream out(&arrBlock, QIODevice::WriteOnly);

    out.setVersion(12);
    out << quint16(0) << str;
    out.device()->seek(0);
    out << quint16(arrBlock.size() - sizeof(quint16));
    pSocket->write(arrBlock);
    pSocket->flush();
    pSocket->waitForBytesWritten(-1);
« Последнее редактирование: Февраль 13, 2011, 23:20 от Madgeniy » Записан
G-virus
Гость
« Ответ #3 : Февраль 13, 2011, 23:56 »

Цитата: Madgeniy link=topic=16260.msg111693#msg111693 date=1297626997
[code
   for (;Подмигивающий {
    
            }
[/code]

Код отправки сообщения с клиента:

Код:
    QDataStream out(&arrBlock, QIODevice::WriteOnly);

Насколько я помню, QDataStream out() принимает указатель на socket. for(;Подмигивающий это задело Веселый Впервые подобное вижу, обычно while(true) пишут Улыбающийся
Записан
Madgeniy
Гость
« Ответ #4 : Февраль 14, 2011, 09:13 »

Тыдыщ. Пример скопипастен из книги Шлее "Профессиональное программирование в QT".
Что касается for, то это просто копипасТ)
« Последнее редактирование: Февраль 14, 2011, 09:46 от Madgeniy » Записан
Madgeniy
Гость
« Ответ #5 : Февраль 14, 2011, 09:15 »

QDataStream ( QIODevice * d )
QDataStream ( QByteArray * a, QIODevice::OpenMode mode )
« Последнее редактирование: Февраль 14, 2011, 09:46 от Madgeniy » Записан
Madgeniy
Гость
« Ответ #6 : Февраль 14, 2011, 20:58 »

Хм.

Код:
        blockSize = 0;
    }

    //парсинг str
    strings = str.split("#");

Надо было скобку чуть позже поставить:

Код:
   blockSize = 0;
    //парсинг str
    strings = str.split("#");
}
Записан
Zmeishe
Гость
« Ответ #7 : Февраль 15, 2011, 08:40 »

Иногда помогает воспользоваться поиском
Записан
Madgeniy
Гость
« Ответ #8 : Февраль 15, 2011, 09:08 »

Я умею, правда, проблема-то у меня совсем в другом была  Строит глазки
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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