Название: Не могу отправить файл по 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()); }
|