| 
 Название: Не могу отправить файл по tcpSocket
 Отправлено: styu от Сентября 02, 2014,  21:13
 
 Здравствуйте, уважаемые программисты! Недавно программирую в Qt и у меня возникли сложности с отправкой файла с сервера с помощью TcpSocket клиенту.
 Код сервера:
 Сервер:
 Код C++ (QT)
 void server::writeFile()
 {
 QTcpSocket* writeFileSocket = (QTcpSocket*)sender();
 QFile file ("/home/00001-150713_a11.txt");
 file.open(QIODevice::ReadOnly);
 QByteArray buf = file.readAll();
 writeFileSocket->write(buf, buf.size());
 writeFileSocket->flush();
 }
 В QByteArray файл записывается, а в writeFileSocket не считывается. Не могу понять в чем причина. Помогите, пожалуйста
 
 Клиент:
 
 Код C++ (QT)
 void Client::readFile()
 {
 QFile file("/home/my.txt");
 file.open(QIODevice::WriteOnly);
 QByteArray arrFile = tcpSocketReadFile->readAll();
 file.write(arrFile);
 file.close();
 }
 
 
 
 Название: Re: Не могу отправить файл по tcpSocket
 Отправлено: torwig от Сентября 02, 2014,  22:10
 
 Наверное, кода маловато приведено.К какому сигналу коннектится writeFile()?
 Если правда в QByteArray файл записывается, а в сокет нет, можно проверить, какое значение возвращает writeFileSocket->write(buf, buf.size()); И вроде можно просто написать writeFileSocket->write(buf);
 На клиенте readFile() я так понимаю к сигналу readyRead() подцеплен?
 Можно обставить qDebug() и смотреть, что там в этих QByteArray, проверять результат операции file.open().
 
 Название: Re: Не могу отправить файл по tcpSocket
 Отправлено: Bepec от Сентября 02, 2014,  22:51
 
 Хватит маяться самодеятельностью. Берём wireshark, ставим порт и видим всё что отправляется - принимается.
 Но если уж код оформить в тег не можем кнопкой [  #  ], то проблема в коде программы.
 
 Название: Re: Не могу отправить файл по tcpSocket
 Отправлено: Old от Сентября 03, 2014,  04:23
 
 Скорее всего потому, что данные сразу не приходят. 
 Название: Re: Не могу отправить файл по tcpSocket
 Отправлено: styu от Сентября 03, 2014,  09:47
 
 Это полный код сервера #include "server.h"#include "ui_server.h"
 
 server::server(QWidget *parent) :
 QMainWindow(parent),
 ui(new Ui::server)
 {
 ui->setupUi(this);
 QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
 sessionOpened();
 fortunes<< tr("Ready");
 connect(tcpServer, SIGNAL(newConnection()), this, SLOT(write()));
 }
 
 server::~server()
 {
 delete ui;
 }
 
 void server::sessionOpened()
 {
 tcpServer = new QTcpServer(this);
 if (!tcpServer->listen(QHostAddress::Any,3333)) {
 QMessageBox::critical(this, tr("Server"),
 tr("Unable to start the server: %1.")
 .arg(tcpServer->errorString()));
 close();
 return;
 }
 
 QString ipAddress;
 QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
 for (int i = 0; i < ipAddressesList.size(); ++i) {
 if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
 ipAddressesList.at(i).toIPv4Address()) {
 ipAddress = ipAddressesList.at(i).toString();
 break;
 }
 }
 ui->lineEdit->setText(ipAddress);
 
 if (ipAddress.isEmpty())
 ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
 ui->lineEdit->setText(ipAddress);
 port = tcpServer->serverPort();
 ui->lineEdit_2->setText(QString::number(port));
 
 }
 
 
 void server::write()
 {
 QByteArray block;
 QDataStream out(&block, QIODevice::WriteOnly);
 out.setVersion(QDataStream::Qt_4_0);
 
 out << (quint16)0;
 out << fortunes.at(qrand() % fortunes.size());
 out.device()->seek(0);
 out << (quint16)(block.size() - sizeof(quint16));
 
 
 clientConnection = tcpServer->nextPendingConnection();
 connect(clientConnection, SIGNAL(disconnected()),
 clientConnection, SLOT(deleteLater()));
 
 clientConnection->write(block);
 connect(clientConnection, SIGNAL(readyRead()),this, SLOT(read()));
 }
 
 void server::read()
 {
 QTcpSocket* dataSender = (QTcpSocket*)sender();
 QDataStream in(dataSender);
 QString str;
 in >> str;
 ui->lineEdit_3->setText(str);
 if (str == "START")
 {
 writeFile();
 }
 }
 
 
 void server::writeFile()
 {
 
 QTcpSocket* writeFileSocket = (QTcpSocket*)sender();
 QFile file ("/home/tatyana/41101-040313.a11");    // 00001-150713_a11.txt");
 file.open(QIODevice::ReadOnly);
 QByteArray buf = file.readAll();
 int iii = buf.size();
 qDebug() << buf.constData();
 writeFileSocket->write(buf, buf.size());
 }
 
 Название: Re: Не могу отправить файл по tcpSocket
 Отправлено: styu от Сентября 03, 2014,  09:48
 
 Это полный код клиента:   #include "client.h"
 #include "ui_client.h"
 
 Client::Client(QWidget *parent) :
 QMainWindow(parent),
 ui(new Ui::Client)
 {
 ui->setupUi(this);
 
 QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
 ui->label_2->setText("<font color =\"#ff0000\">Подключение ...</font>");
 
 ipAddress = "192.168.0.111"; //220;
 port = 3333;
 
 fortunes<< tr("Start");
 
 tcpSocket = new QTcpSocket(this);
 tcpSocketWrite = new QTcpSocket(this);
 
 connect(tcpSocketWrite, SIGNAL(connected()), SLOT(slotConnected()));
 
 connect(tcpSocket, SIGNAL(readyRead()), SLOT(slotReadyRead()));
 connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
 this,SLOT(slotError(QAbstractSocket::SocketError)));
 }
 
 Client::~Client()
 {
 delete ui;
 tcpSocket->close();
 tcpSocket->disconnectFromHost();
 
 tcpSocketWrite->close();
 tcpSocketWrite->disconnectFromHost();
 }
 
 
 void Client::slotReadyRead()
 {
 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;
 
 QString nextFortune;
 in >> nextFortune;
 
 if (nextFortune == currentFortune) {
 QTimer::singleShot(0, this, SLOT(requestNew()));
 return;
 }
 
 currentFortune = nextFortune;
 
 if (currentFortune == "Ready")
 {
 tcpSocketWrite->connectToHost(ipAddress,port);
 }
 tcpSocket->disconnectFromHost();
 
 }
 
 
 void Client::slotError(QAbstractSocket::SocketError err)
 {
 switch (err) {
 case QAbstractSocket::RemoteHostClosedError:
 break;
 case QAbstractSocket::HostNotFoundError:
 QMessageBox::information(this, tr("Client"),
 QObject::trUtf8(" Хост не может быть найден."
 "Пожалуйста, проверьте имя хоста и номер порта"));
 break;
 case QAbstractSocket::ConnectionRefusedError:
 QMessageBox::information(this, tr("Client"),
 QObject::trUtf8("Нет соединения с сервером! "
 "Сервер не был запущен. "
 "Запустите, пожалуйста, сервер. "));
 break;
 default:
 QMessageBox::information(this, tr("Client"),
 QObject::trUtf8("Ошибка: %1.")
 .arg(tcpSocket->errorString()));
 }
 }
 
 void Client::readFile()
 {
 QFile file("/home/tatyana/my.txt");
 file.open(QIODevice::WriteOnly);
 QByteArray arrFile = tcpSocketReadFile->readAll();
 int jjj = arrFile.size();
 file.write(arrFile);
 file.close();
 }
 
 void Client::slotConnected()
 {
 QDataStream out(tcpSocketWrite);
 out.setVersion(QDataStream::Qt_4_8);
 out << tr("START");
 ui->textEdit->append(QObject::trUtf8("Отправлен сигнал к запуску чтения!"));
 tcpSocketWrite->close();
 tcpSocketWrite->disconnectFromHost();
 
 tcpSocketReadFile = new QTcpSocket(this);
 tcpSocketReadFile->connectToHost(ipAddress, port);
 connect(tcpSocketReadFile, SIGNAL(readyRead()), this, SLOT(readFile()));
 }
 
 
 void Client::on_pushButton_3_clicked()
 {
 int f ,cod ,IsLoopBack;
 QString ip;
 for( int index = 0; index < QNetworkInterface::allInterfaces().count(); index++)
 {
 QNetworkInterface current = QNetworkInterface::interfaceFromIndex( index + 1);
 f=current.flags();
 cod =f & QNetworkInterface::IsUp; //карта д.б. активна
 IsLoopBack = f & QNetworkInterface::IsLoopBack; //петлевой интерфейс
 if( cod ==QNetworkInterface::IsUp || IsLoopBack != QNetworkInterface::IsLoopBack)
 {
 if( current.isValid() )  // нет сетевого интерфейса
 {
 if (current.flags().testFlag(QNetworkInterface::IsRunning))
 ui->label_2->setText("<font color=\"#00aa00\">Сеть подключена ...</font>");
 else
 ui->label_2->setText("<font color =\"#ff0000\">Нет соединения...</font>");
 }
 }
 }
 }
 
 
 
 void Client::requestNew()
 {
 blockSize = 0;
 tcpSocket->abort();
 tcpSocket->connectToHost(ipAddress,port);
 }
 
 void Client::on_pushButton_4_clicked()
 {
 requestNew();
 }
 
 Название: Re: Не могу отправить файл по tcpSocket
 Отправлено: torwig от Сентября 03, 2014,  14:41
 
 Хм...Давайте проясним логику приложения.
 Итак есть сервер. Есть клиент, там у вас 2 сокета.
 При подключении tcpSocket к серверу, сервер напишет в сокет Ready. Клиент, получив это, отправит серверу Start, и отключится.
 После этого с клиента сокет tcpSocketWrite подключится и по идее тоже получит Ready, ...дальше я заблудился)
 И все же что должен делать код, Вашими словами.
 
 
 Название: Re: Не могу отправить файл по tcpSocket
 Отправлено: Bepec от Сентября 03, 2014,  15:07
 
 Всё довольно просто. ТС продублировал TCPSocket, запутался в них и в результате у него получается шишь :) Вот тут бяка.  void Client::slotConnected(){// Да мы подключились tcpSocketWrite'ром.
 QDataStream out(tcpSocketWrite);
 out.setVersion(QDataStream::Qt_4_8);
 // запишем в массив СТАРТ
 out << tr("START");
 // ага и выведем сообщение что всё хорошо
 ui->textEdit->append(QObject::trUtf8("Отправлен сигнал к запуску чтения!"));
 // Эй, эй, парни - вы куда? Я ещё ничего не отправил серверу!!!!
 tcpSocketWrite->close();
 // АААА... Я закрыт... Я не смог выполнить миссию
 tcpSocketWrite->disconnectFromHost();
 // НЕЕЕТ, я не виноват, не бейте!!! Это всё программист!!!!!!
 }
 Название: Re: Не могу отправить файл по tcpSocket
 Отправлено: styu от Сентября 03, 2014,  20:28
 
 Хм...Давайте проясним логику приложения.
 Итак есть сервер. Есть клиент, там у вас 2 сокета.
 При подключении tcpSocket к серверу, сервер напишет в сокет Ready. Клиент, получив это, отправит серверу Start, и отключится.
 После этого с клиента сокет tcpSocketWrite подключится и по идее тоже получит Ready, ...дальше я заблудился)
 И все же что должен делать код, Вашими словами.
 
 Именно так все и происходит. А хотелось бы, чтобы после того, как клиент отправит серверу Start, и сервер этот Start получил, сервер отправит в ответ в сокет файл, а клиент его получит. А получается, что tcpSocketWrite сокет с клиента не получает файл, а получает, как Вы и сказали Ready
 Название: Re: Не могу отправить файл по tcpSocket
 Отправлено: styu от Сентября 03, 2014,  20:48
 
 void Client::slotConnected(){// Да мы подключились tcpSocketWrite'ром.
 QDataStream out(tcpSocketWrite);
 out.setVersion(QDataStream::Qt_4_8);
 // запишем в массив СТАРТ
 out << tr("START");
 // ага и выведем сообщение что всё хорошо
 ui->textEdit->append(QObject::trUtf8("Отправлен сигнал к запуску чтения!"));
 // Эй, эй, парни - вы куда? Я ещё ничего не отправил серверу!!!!
 tcpSocketWrite->close();
 // АААА... Я закрыт... Я не смог выполнить миссию
 tcpSocketWrite->disconnectFromHost();
 // НЕЕЕТ, я не виноват, не бейте!!! Это всё программист!!!!!!
 }
tcpSocketWrite как раз свою миссию выполнил, Start он отправил и отключился
 Название: Re: Не могу отправить файл по tcpSocket
 Отправлено: Bepec от Сентября 03, 2014,  21:09
 
 Помогите нюше найти в этом коде tcpSocketWrite->write(buf)? :) void Client::slotConnected(){// Да мы подключились tcpSocketWrite'ром.
 QDataStream out(tcpSocketWrite);
 out.setVersion(QDataStream::Qt_4_8);
 // запишем в массив СТАРТ
 out << tr("START");
 // ага и выведем сообщение что всё хорошо
 ui->textEdit->append(QObject::trUtf8("Отправлен сигнал к запуску чтения!"));
 // Эй, эй, парни - вы куда? Я ещё ничего не отправил серверу!!!!
 tcpSocketWrite->close();
 // АААА... Я закрыт... Я не смог выполнить миссию
 tcpSocketWrite->disconnectFromHost();
 // НЕЕЕТ, я не виноват, не бейте!!! Это всё программист!!!!!!
 }
PS ни к чему не принуждающий совет - начните новый проект клиента, в котором будет только один QTcpSocket и который будет вести диалог с сервером, а не "одна реплика на один сокет".
 Название: Re: Не могу отправить файл по tcpSocket
 Отправлено: styu от Сентября 03, 2014,  21:25
 
 QDataStream out(tcpSocketWrite); а это как же? S ни к чему не принуждающий совет - начните новый проект клиента, в котором будет только один QTcpSocket и который будет вести диалог с сервером, а не "одна реплика на один сокет". Я как раз собиралась это сделать
 Название: Re: Не могу отправить файл по tcpSocket
 Отправлено: Bepec от Сентября 04, 2014,  08:29
 
 Таки да, я ошибался :) Извиняюсь. Сказывается малый опыт работы с DataStream. update:  Тогда ошибка вот тут. writeFile вы вызываете из метода сервера.  writeFileSocket у вас в этом случае = сервер. Но т.к. у вас отсутствует проверка на валидность указателя и вы применяете C преобразование, я удивлён что у вас ничего не вылетает.  Тут вам вместо (QTcpSocket*) надо использовать qobject_cast<QTcpSocket*>() и проверять указатель на 0. (Это не заставит программу работать, она неверна, но зато это даст необходимую вам обработку ошибки и вы увидите где проваливается процесс).  К тому же вы немного не понимаете принцип работы асинхронного соединения. Нет никакой гарантии, что в момент writeFile tcpSocketReadFile  уже создан и подсоединился.  Именно поэтому совет остаётся в силе - реализуйте свой протокол с одним QTcpSocket.  void server::writeFile(){
 
 QTcpSocket* writeFileSocket = (QTcpSocket*)sender();
 QFile file ("/home/tatyana/41101-040313.a11");    // 00001-150713_a11.txt");
 file.open(QIODevice::ReadOnly);
 QByteArray buf = file.readAll();
 int iii = buf.size();
 qDebug() << buf.constData();
 writeFileSocket->write(buf, buf.size());
 }
 
 |