Russian Qt Forum

Qt => Работа с сетью => Тема начата: Raast от Март 14, 2009, 20:33



Название: Передача файла по TCP
Отправлено: Raast от Март 14, 2009, 20:33
Привет всем!
Передо мной встала обычная проблема: мне необходимо переслать любой файл (двоичный в том числе) от клиента серверу и сохранить его на сервере. 
Во всех выдержках из книг осуществляется передача строк и текущего времени от клиента к серверу или что-то на подобии этого!!!
А если попробуем сделать, как это сделано в примере в книге, то передается максимум 100 КБ

Как решить проблему???Помогите

Заранее спасибо.


Название: Re: Передача файла по TCP
Отправлено: Rcus от Март 14, 2009, 21:34
Ну если проблема обычная то и решение есть обычное: FTP /** \see ./examples/network/ftp/ */ или этот протокол чем-то не подходит?


Название: Re: Передача файла по TCP
Отправлено: Magvaj от Март 15, 2009, 12:21
Среди примеров в книгах есть большой глюк: все после команды записи в сокет закрывают его. Сам с этим сталкивался. Нужно просто следить за сигналами статусов отправки данных и закрывать сокет только после завершения.  ;)


Название: Re: Передача файла по TCP
Отправлено: Raast от Март 16, 2009, 23:40
Пытаюсь передать файл....

   
Код
C++ (Qt)
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...");
}
 

Код сервера

Код
C++ (Qt)
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 это всего лишь одна процедура...
Помогите пожалуйста!!!

Автор: Magvaj
Цитата
Среди примеров в книгах есть большой глюк: все после команды записи в сокет закрывают его. Сам с этим сталкивался. Нужно просто следить за сигналами статусов отправки данных и закрывать сокет только после завершения.


А зачем сокет держать открытым??? Передал информацию от  клиента к серверу и закрылось соединение, не так ли???


P.S. Я уже целые две недели мудохаюсь, не могу передать нормального размера файл, честное слово...помогите кто может


//Пользуйся тегом КОД для форматирования исходного кода


Название: Re: Передача файла по TCP
Отправлено: Rcus от Март 17, 2009, 06:36
Интересно :) вы пытаетесь передать файл одним пакетом уровня приложения, при том ограничив поле длины двумя байтами :) Так или иначе даже если увеличить поле длины до 8 байт этот протокол не сможет справлять с передачей файлов большого размера, но уже по другим причинам.


Название: Re: Передача файла по TCP
Отправлено: Raast от Март 17, 2009, 23:27
Ну и как мне тогда с этим побороться???

Прочитал в других источниках, что проблема возможна: 1)поменять местами сервер и клиент- передачу файла??
2) разбить файл на блоки не более 48 КБ и их передавать