Название: НЕ доходят сообщения с сервера
Отправлено: 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 не вариант так как текст может быть кто знает какой, и чем разбивать можно только догадываться... ЗАранее спасибо за помощь...
Название: Re: НЕ доходят сообщения с сервера
Отправлено: merke от Январь 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.cppC++ (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.hC++ (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.cppC++ (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); }
Название: Re: НЕ доходят сообщения с сервера
Отправлено: Madgeniy от Февраль 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);
Название: Re: НЕ доходят сообщения с сервера
Отправлено: G-virus от Февраль 13, 2011, 23:56
for (;;) { } [/code] Код отправки сообщения с клиента: QDataStream out(&arrBlock, QIODevice::WriteOnly);
Насколько я помню, QDataStream out() принимает указатель на socket. for(;;) это задело :D Впервые подобное вижу, обычно while(true) пишут :)
Название: Re: НЕ доходят сообщения с сервера
Отправлено: Madgeniy от Февраль 14, 2011, 09:13
Тыдыщ. Пример скопипастен из книги Шлее "Профессиональное программирование в QT". Что касается for, то это просто копипасТ)
Название: Re: НЕ доходят сообщения с сервера
Отправлено: Madgeniy от Февраль 14, 2011, 09:15
QDataStream ( QIODevice * d ) QDataStream ( QByteArray * a, QIODevice::OpenMode mode )
Название: Re: НЕ доходят сообщения с сервера
Отправлено: Madgeniy от Февраль 14, 2011, 20:58
Хм. blockSize = 0; }
//парсинг str strings = str.split("#"); Надо было скобку чуть позже поставить: blockSize = 0; //парсинг str strings = str.split("#"); }
Название: Re: НЕ доходят сообщения с сервера
Отправлено: Zmeishe от Февраль 15, 2011, 08:40
Иногда помогает воспользоваться поиском (http://www.prog.org.ru/index.php?topic=12980.msg84828#msg84828)
Название: Re: НЕ доходят сообщения с сервера
Отправлено: Madgeniy от Февраль 15, 2011, 09:08
Я умею, правда, проблема-то у меня совсем в другом была ::)
|