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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Чтение QTcpSocket и лишний символ перевода каретки  (Прочитано 6420 раз)
kosproger
Гость
« : Сентябрь 16, 2012, 19:34 »

Доброго времени суток!
Делаю приложения для работы с FTP. Проверяется удаленная папка и скачиваются pdf файлы. Возникла следующая проблема: При скачивании файла, перед символом "\n" дописывается лишний "\r" и нарушается структура скачанных файлов. Пробовал при скачивании заменять "\r\n" на "\n", но файл может сам по себе содержать "\r\n" и тогда также возникает проблема.
Реализовао следующим образом: Управляющее соединение - socket, соединение передачи данных = dataSocket.
PdfPrinter.ppp:
Код:
PdfPrinter::PdfPrinter(QObject *parent) : QObject(parent)
{
..........
    socket = new QTcpSocket();
    dataSocket = new QTcpSocket();
    connect(socket, SIGNAL(connected()), SLOT(onConnected()), Qt::DirectConnection);
    connect(socket, SIGNAL(readyRead()), SLOT(onRead()), Qt::DirectConnection);
    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(onError(QAbstractSocket::SocketError)), Qt::DirectConnection);
    connect(socket, SIGNAL(disconnected()), SLOT(onDisconnected()), Qt::DirectConnection);
    connect(dataSocket, SIGNAL(readyRead()), SLOT(onDataRead()), Qt::DirectConnection);
............
}

void PdfPrinter::connectFtp()
{
    socket->connectToHost(server,21);
    socket->waitForConnected();
}

void PdfPrinter::onRead()
{
    QString message=(QString(socket->readAll()));
.............// различные ответы FTP
                    if (message.startsWith("227")) {
                        QRegExp regExp("[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3}");
                        int pos = regExp.indexIn(message);
                        if (pos > -1) {
                            QStringList addresses = regExp.capturedTexts().at(0).split(",");
                            QString connectAddr = "";
                            for (int i = 0; i < 4; i++) {
                                connectAddr += addresses.at(i);
                                if (i < 3)
                                    connectAddr += ".";
                            }
                            int port = addresses.at(4).toInt() * 256 + addresses.at(5).toInt();
                            if (files.isEmpty()) { //files - список файлов в каталоге. Если пустой - отправляем команду получения списка
                                sendToServer("NLST\r\n");
                                qDebug("Listing...");
                                fflush(stdout);
                            } else { //в противоположном случае качаем первый файл из списка
                                sendToServer("RETR " + files.first() + "\r\n");
                                qDebug(QString("Downloading " + files.first() + "...").toUtf8());
                                fflush(stdout);
                            }
                            dataSocket->connectToHost(connectAddr,port);
                            dataSocket->waitForConnected();
                        }
                    } else {
..........
                            if (message.startsWith("226")) {
                                if (files.isEmpty() || isListing) {
                                    qDebug("Listing finished.");
                                } else {
                                    qDebug(QString("Downloading " + files.first() + " finished.").toUtf8());
                                    if (files.count() > 1)
                                        files.removeFirst();
                                    else
                                        files.clear();
                                }
                                dataSocket->disconnectFromHost();
                                dataSocket->close();
                                sendToServer("PASV\r\n");
                                fflush(stdout);
                            }
                        }
.............
}

void PdfPrinter::onDataRead()
{
    if (files.isEmpty()) {
        isListing = true;
        QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf-8"));
        QString data = QString(dataSocket->readAll());
        QStringList fileNames = data.split("\r\n");
        for (int i = 0; i < fileNames.count(); i++) {
            if (!fileNames.at(i).isEmpty()) {
                files.append(fileNames.at(i));
            }
        }
    } else {
        QFile *file = new QFile(filePath + "/" + files.first());
        if (isListing) {
            if (file->exists())
                file->remove();
        }
        isListing = false;
        file->open(QIODevice::Append);
        file->write(dataSocket->readAll()); //вот тут получается ByteArray c лишними \r перед \n
        file->waitForBytesWritten(100000);
        file->close();
        delete file;
    }
}
в чем может быть дело?
Записан
V1KT0P
Гость
« Ответ #1 : Сентябрь 16, 2012, 20:03 »

Проверь что у тебя выдает:
Код
C++ (Qt)
bool QIODevice::isTextModeEnabled () const
По умолчанию вроде должен быть отключенным. Если включен то естественно будет заменять, надо просто выключить:
Код
C++ (Qt)
void QIODevice::setTextModeEnabled ( bool enabled )
Записан
Serr500
Гость
« Ответ #2 : Сентябрь 16, 2012, 20:08 »

FTP-сервер в бинарный режим переключен?
Записан
kosproger
Гость
« Ответ #3 : Сентябрь 16, 2012, 20:51 »

FTP-сервер в бинарный режим переключен?
Огромное спасибо!!!
Бился двое суток с обработкой входящих данных и не заметил очевидного!
Собственно команда перевода в binary была, только я там сам не заметил лишний символ и отправлял команду в неверном формате))) Перепроверил, исправил!
Прошу прощенья, глупая ошибка Строит глазки

Код:
bool QIODevice::isTextModeEnabled ()
выключен Улыбающийся
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #4 : Сентябрь 17, 2012, 02:21 »

А чем стандартные классы не угодили?
Записан

Гугль в помощь
kosproger
Гость
« Ответ #5 : Сентябрь 17, 2012, 12:30 »

QFtp? Изначально на нем и было реализовано. Но, лучше я буду исправлять свои баги, чем писать различные костыли для отловли его глюков, поэтому переписываю. Тем более что больше не поддерживается и вполне возможно, что потом совсем уберут его. Кроме того, в дальнейшем надо будет использовать другие протоколы, в том числе, возможно и свой. Тут уж без сокетов - никак Улыбающийся
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #6 : Сентябрь 17, 2012, 16:26 »

QNetworkAccessManager тоже вроде бы умеет
Записан

Гугль в помощь
kosproger
Гость
« Ответ #7 : Сентябрь 17, 2012, 19:12 »

Он может стянуть файл с известным адресом. А получить список файлов не сможет. А добавлять QNetworkAccessManager только для скачивания, реализовав все остальное сокетами - смысл?
Записан
SYrok
Гость
« Ответ #8 : Октябрь 10, 2012, 06:33 »

Приветствую всех

по поводу QFtp у меня тоже большие траблы, поэтому начал искать инфу как отказаться от его использования.
проблема в том, что при опросе FTP сервера и скачивание пару файлов, клиент тупо вешается, реализация WatchDog таймера помогает, но это костыль

при чём, если по таймауту отбрасывать зависшее подключение, то оказывается что файлы скачаны (иногда и не скачивает), но вот сигнала done нет, от того и висит

Записан
kosproger
Гость
« Ответ #9 : Октябрь 10, 2012, 19:33 »

Так в чем проблема, QTcpSocket и вперед Улыбающийся
Записан
SYrok
Гость
« Ответ #10 : Октябрь 11, 2012, 04:20 »

так уже начал разбираться, за помощь спасибо
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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