crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> передача файла по TCP
Rastorev
  опции профиля:
сообщение 10.3.2009, 22:00
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 6
Регистрация: 27.2.2009
Пользователь №: 579

Спасибо сказали: 0 раз(а)




Репутация:   0  


Добрый день!
Программа клиент TCP должна передавать информацию о файле и сам файл на сервер TCP и отображать ответ и текущее состояние сервера
Сделано стандартно по примеру QT - обмен строковой информации между клиентом и сервером по TCP/IP происходит через открытый сокет,
теперь я пытаюсь разбить файл на блоки и передаю в сокетный поток, а на сервере принимая каждый блок сохраняю в файл, но в файл выводятся иероглифы вместо нужной информации.
Клиента код.

QFile fileopen(sourceFile);
    targetFile = QFileInfo(sourceFile).fileName();
    char block[1024];

    if (fileopen.open(QFile::ReadWrite)) {
        QByteArray arrayBlock;
        QDataStream vivod(&arrayBlock, QIODevice::WriteOnly);
        vivod.setVersion(10);
        vivod << quint16(0) << quint8('S') << targetFile;

        fileopen.seek(0);
        while(!fileopen.atEnd()) {
             quint64 in;
             in = fileopen.read(block, sizeof(block));
            vivod << in;
            }
        vivod.device()->seek(0);
        vivod << quint16(arrayBlock.size() - sizeof(quint16));
        //записываем данные в сокет
        tcpSocket.write(arrayBlock);
        }
    statusLabel->setText("Sending File...");
}

Код сервера

    QDataStream in(this);
    in.setVersion(10);
    if (nextBlockSize == 0) {
        if (bytesAvailable() < sizeof(quint16))
            return;
        in >> nextBlockSize;
    }
    if (bytesAvailable() < nextBlockSize)
        return;

    quint8 requestType;
    QString targetFile;

    in >> requestType;
    if (requestType == 'S') {
        in >> targetFile;
        generateRandomTrip(targetFile);
        QFile target(targetFile);
        if(target.open(QIODevice::WriteOnly)){
            char block[1024];

//может быть ошибка где-то сдесь

            while(!in.atEnd()) {
                quint64 tofile;
                in >> tofile;
                target.write(block,tofile);
            }
        }
        target.close();
        QDataStream out(this);
        out << quint16(0xFFFF);
        }
    nextBlockSize = 0;
    close();


Нужно сделать так чтобы сервер создавал файл и содержимое полученное от клиента получалось нормальным.
Подскажите пожалуйста, в чем ошибка? может решить эту проблему по другому? Может быть есть какие-нибудь нюансы которые я не учел?
Заранее спасибо!!!
Причина редактирования: используйте тэг code
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 10.3.2009, 22:34
Сообщение #2


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


Rastorev,
почему бы не сделать в клиенте и в сервере связь потока данных напрямую с сокетом, исползуя QDataStream::QDataStream(QIODevice*) ?


P.S/
обрамляйте код тегом code читать неудобно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Rastorev
  опции профиля:
сообщение 11.3.2009, 0:53
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 6
Регистрация: 27.2.2009
Пользователь №: 579

Спасибо сказали: 0 раз(а)




Репутация:   0  


не мог бы ты описать более конкретней ??
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 11.3.2009, 20:57
Сообщение #4


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


Цитата(kwisp @ 10.3.2009, 22:34) *
QDataStream::QDataStream(QIODevice*)

есть такой конструктор.
qTcpSocket наследник QIODevice
конструируишь поток передавая указатель на сокет открываешь сокет и шлешь данные через поток.
попробуй может окажется удобнее.
а вообще у меня сделано так :
....
SLReadPH() {//слот завязан на сигнал сокета readyRead()
int res;
do
res=ReadSock();
while(res&&this->bytesAvailable()>6);
}
....
ReadSock(){
...
char rawhead[sizeof(SHead)];
this->readData(rawhead,sizeof(SHead)))
...

}

проблем вроде нет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Rastorev
  опции профиля:
сообщение 15.3.2009, 23:45
Сообщение #5


Новичок


Группа: Новичок
Сообщений: 6
Регистрация: 27.2.2009
Пользователь №: 579

Спасибо сказали: 0 раз(а)




Репутация:   0  


Но как вы реализовали передачу - наподобие "обратной связи",т.е. также this->writeData(char *s,sizeof(s)))?????

И нет ли проблемы в передачи файла большего размера чем 100 КБ???
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 16.3.2009, 9:41
Сообщение #6


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


Цитата(Rastorev @ 15.3.2009, 23:45) *
И нет ли проблемы в передачи файла большего размера чем 100 КБ???

а у вас есть??? какого рода проблемы??
может надо почитать про протокол Tcp/ip я точно не в курсе как там реализована передача файлов и есть ли проблемы с передачей файлов больших размеров. честно говоря сомневаюсь что должны быть проблемы.

дело в том что я передаю не совсем файлы а сообщения некоего протокола. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Rastorev
  опции профиля:
сообщение 16.3.2009, 22:12
Сообщение #7


Новичок


Группа: Новичок
Сообщений: 6
Регистрация: 27.2.2009
Пользователь №: 579

Спасибо сказали: 0 раз(а)




Репутация:   0  


Пытаюсь передать файл....
    if (fileopen.open(QFile::ReadWrite)) {
        QByteArray arrayBlock;
        QDataStream vivod(&arrayBlock, QIODevice::WriteOnly);
        vivod.setVersion(10);
        vivod << quint16(0) << quint8('S') << targetFile;

        fileopen.seek(0);
       [b] while[/b](!fileopen.atEnd()) {
             quint64 in;
            [b] in = fileopen.read(block, sizeof(block));
            vivod.writeRawData(block,in);[/b]
            }
        vivod.device()->seek(0);
        vivod << quint16(arrayBlock.size() - sizeof(quint16));
        //записываем данные в сокет
        tcpSocket.write(arrayBlock);
        }
    statusLabel->setText("Sending File...");
}


Код сервера
 QDataStream in(this);
    in.setVersion(10);
    if (nextBlockSize == 0) {
        if (bytesAvailable() < sizeof(quint16))
            return;
        in >> nextBlockSize;
    }
    if (bytesAvailable() < nextBlockSize)
        return;

    quint8 requestType;
    QString targetFile;

    in >> requestType;
    if (requestType == 'S') {
        in >> targetFile;
        generateRandomTrip(targetFile);
        QFile target(targetFile);
        if(target.open(QIODevice::WriteOnly)){
            char block[1024];

//самое основное - пытаюсь считать этот файл из сетевого потока

            while(!in.atEnd()) {
                quint64 tofile = in.readRawData(block,sizeof(block));
    
                target.write(block,tofile);
...

Получается что обычный *.txt и даже *.dll меньше 60 КБ могу передать, а 1МБ слабо(((((
Я понимаю что это целый протокол, но это не велосипед изобретать!!!в Delphi это всего лишь одна процедура...
Помогите пожалуйста!!!


P.S. Я уже целые две недели мудохаюсь, не могу передать нормального размера файл, честное слово
Причина редактирования: используй тэг code
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Rastorev
  опции профиля:
сообщение 17.3.2009, 23:02
Сообщение #8


Новичок


Группа: Новичок
Сообщений: 6
Регистрация: 27.2.2009
Пользователь №: 579

Спасибо сказали: 0 раз(а)




Репутация:   0  


Спасибо хоть и на этом...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 18.3.2009, 9:04
Сообщение #9


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Ты немного не так делаешь. Правильней было бы сделать своего рода протокол передачи файла.
Перед началом передачи файла отправляешь принимающей стороне 4 байта, в которые записан размер файла, дальше можно передать имя файла(пуская этот блок будет 64 байта), после чего уже идет сам файл, пример структуры передачи:
struct sFileData
{
   int nFileSize;
   char pFileName[64];
};

Отправляешь данную структуру примерно так:
sFileData fd;
fd.nFileSize = 1024;
memset( fd.pFileName, 0, sizeof(fd.pFileName));
strcpy( fd.pFileName, "testfile.txt");
socket.write( (const char*)&fd, sizeof( fd));

далее также с помощью socket.write отправляешь сам файл.

Сообщение отредактировал ViGOur - 18.3.2009, 9:07
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
LE0N
  опции профиля:
сообщение 18.3.2009, 10:31
Сообщение #10


Студент
*

Группа: Участник
Сообщений: 97
Регистрация: 10.3.2009
Из: Беларусь
Пользователь №: 604

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата
Я понимаю что это целый протокол, но это не велосипед изобретать!!!в Delphi это всего лишь одна процедура...

о_О. Чего ж вы на делфи эту прогу не пишете? ))))
Попривыкали, блин, "программировать" компонентами.... :huh:
Цитата
sFileData fd;
fd.nFileSize = 1024;
memset( fd.pFileName, 0, sizeof(fd.pFileName));
strcpy( fd.pFileName, "testfile.txt");
socket.write( (const char*)&fd, sizeof( fd));

Уххх, как же душа возрадовалась, когда чистый СИ увидел :))
Цитата
Я уже целые две недели мудохаюсь, не могу передать нормального размера файл, честное слово

Так, может быть, вы расскажете что происходит, когда вы пытаетесь передать файл больше 60кб ?
И это...Мне вот просто интересно...А когда вы долбались 2 недели, проверить во время получения данных на ошибки, которые возратит QDataStream тоже ни как?
И, последний вопрос,
Цитата
quint64 tofile = in.readRawData(block,sizeof(block));

Вы знаете, что произойдёт, если в tofile попадёт -1 ? Указывающая на то, что при получении произошла ошибка.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.3.2024, 13:42