Модераторы: Snowy, Poseidon, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Отправка файла с Indy клиента на Indy сервер, Прошу указать, что делаю не так. 
V
    Опции темы
Диас
Дата 26.6.2006, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 124
Регистрация: 11.6.2006

Репутация: нет
Всего: нет



Здравствуйте. Необходимо отправить файл с клиента на сервер. Использую Delphi 7 и Indy 9. На клиенте пишу:

Код

procedure TForm2.Button1Click(Sender: TObject);
var
    fstream:tfilestream;
begin
with form1.IdTCPClient1 do
  try
   Connect;
   GetResponse(200);
   WriteLn('RegisterUser '+username);
   fstream:=tfilestream.Create(filename,fmOpenRead);
   WriteStream(fstream,true,true);
   GetResponse(200);
end;


filename берется из OpenDialog'а.

А на сервере обработчик команды RegisterUser имеет вид:

Код

procedure TForm1.IdTCPServer1cmdRegisterUserCommand(ASender: TIdCommand);
var 
    ...
    stream:tstream;
begin
 ...
 CoInitialize(nil);
 stream:=TMemoryStream.Create;
 try
  ASender.Thread.Connection.ReadStream(stream);
  stream.Position:=0;
  image1.Picture.Bitmap.LoadFromStream(stream);
 finally
  stream.Free;
 end;
 ...
end;


Но сервер зависает на строчке 
"ASender.Thread.Connection.ReadStream(stream);"
Может надо как-то передать, что стрим закончен? Или может предварительно отправить размер передаваемого файла?
Кто знает в чем дело, прошу указать на недостатки/ошибки.  
PM MAIL   Вверх
_hunter
Дата 26.6.2006, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 5
Всего: 98



поиском пользуемся:
http://forum.vingrad.ru/index.php?showtopic=42410 


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Диас
Дата 26.6.2006, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 124
Регистрация: 11.6.2006

Репутация: нет
Всего: нет



Разумеется, это в первую очередь! И только, потому что там нет моего случая, пришлось создать тему! 

Это сообщение отредактировал(а) Диас - 30.6.2006, 11:54
PM MAIL   Вверх
Диас
Дата 29.6.2006, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 124
Регистрация: 11.6.2006

Репутация: нет
Всего: нет



Уже пробую делать так: взято с примера Indy9Demos, ImageServer. Только пришлось немного переделать, потому что в примере пересылка тоже идет от сервера к клиенту.

Отправка с клиента:
Код

procedure TForm2.Button1Click(Sender: TObject);
var
    filename:string;
    fstream:tfilestream;
begin
 filename:=OpenDialog1.FileName;
 with form1.IdTCPClient1 do
 try
   Connect;
   GetResponse(200);
   WriteLn('File');
    //отправка файла
    fstream:=tfilestream.Create(filename,fmOpenRead+fmShareDenyNone);
    OpenWriteBuffer;
    WriteStream(fstream);
    CloseWriteBuffer;
    Disconnect;
    FreeAndNil(fstream);
    GetResponse(200);
  finally
    Disconnect;
  end;  
end;


На сервере существует CommandHandler - File. Его обработчик:
Код

procedure TForm1.IdTCPServer1cmdFileCommand(ASender: TIdCommand);
var 
    stream:tfilestream; 
begin 
 //прием файла, папка ttt перед приемом пуста
 stream:=TFileStream.Create('c:\ttt\a.bmp',fmCreate); 

  while ASender.Thread.Connection.Connected do
      ASender.Thread.Connection.ReadStream(stream,-1,true);

  freeandnil(stream);
  image1.Picture.LoadFromFile('c:\ttt\a.bmp');
 end;


Проблема 1:
После данной переделки файл отказывается загружаться в Image и даже открываться в Винде, хотя имеет тотже размер и расширение.

Проблема 2:
Как видно из кода сервера, поток читается до тех пор, пока клиент не отсоединится. А мне нужно, чтобы клиент не отсоединялся, чтобы узнал как там все прошло (GetResponse(200)). 
PM MAIL   Вверх
Romikgy
Дата 13.7.2006, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 3
Всего: 146



Цитата(Диас @  29.6.2006,  08:06 Найти цитируемый пост)
Проблема 1:
После данной переделки файл отказывается загружаться в Image и даже открываться в Винде, хотя имеет тотже размер и расширение.

сравни файлы по содержимому, тотал командер это умеет, может просто зануляется файл

Цитата(Диас @  29.6.2006,  08:06 Найти цитируемый пост)
А мне нужно, чтобы клиент не отсоединялся, чтобы узнал как там все прошло (GetResponse(200)).  

не понял что те нужно? 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Snowy
Дата 13.7.2006, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Сначала нужно передать размер передаваемых данных, чтобы сервер знал, сколько байт ему принимать. 
PM MAIL   Вверх
Диас
Дата 13.7.2006, 20:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 124
Регистрация: 11.6.2006

Репутация: нет
Всего: нет



Цитата

не понял что те нужно?


Сервер заканчивает читать поток только после разъединения:
Код

while ASender.Thread.Connection.Connected do
      ASender.Thread.Connection.ReadStream(stream,-1,true);

А мне не надо разъединяться.

Цитата

Сначала нужно передать размер передаваемых данных, чтобы сервер знал, сколько байт ему принимать.

А какое поставить условие? Или где потом на сервере указать сколько байт принимать? 
PM MAIL   Вверх
Snowy
Дата 14.7.2006, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



-1 это и есть читать до дисконнекта.
Хочешь другой результат - задавай размер.
Чтобы его задать, его должен сообщить клиент, ибо серверу абсолютно неизвестен размер файла.

Перед отправкой стрима, отправь 4 байта с длиной файла.
На стороне сервера читай эти 4 байта.
На клиенте отправляй стрим.
На сервере принимай стрим, только вместо -1 указывай принятый размер. 
PM MAIL   Вверх
Диас
Дата 14.7.2006, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 124
Регистрация: 11.6.2006

Репутация: нет
Всего: нет



Все сделал, как ты сказал, файл принимается и идентичен по размеру оригиналу, но по содержимому они разные! При открытии их в блакноте у нового файла имеется пустая строка в начале. Щас попробую через Тотал командер. 
PM MAIL   Вверх
Snowy
Дата 14.7.2006, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 53
Всего: 484



Код

procedure TForm1.IdTCPServer1cmdFileCommand(ASender: TIdCommand);
var 
    stream: TMemoryStream; 
    sz: integer;
begin 
  stream := TMemoryStream.Create;
  with ASender.Thread.Connection do
    while Connected do begin
      sz := ReadInteger;
      ReadStream(stream, sz, false);
  end;
  stream.Position := 0;
  image1.Picture.LoadFromStream(stream);
  freeandnil(stream);
 end;

На клиенте соответственно нужно перед отправкой стрима послать размер WriteInteger;

Добавлено @ 10:35 
Цитата(Диас @  14.7.2006,  09:54 Найти цитируемый пост)
При открытии их в блакноте у нового файла имеется пустая строка в начале.
Это потому что ты делаешь WriteStream(fstream,true,true);
А нужно WriteStream(fstream); 
PM MAIL   Вверх
Диас
Дата 14.7.2006, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 124
Регистрация: 11.6.2006

Репутация: нет
Всего: нет



Короче, все понятно!  smile Это просто были глюки из-за того, что передаваемых параметров было около 20! Стоило перестать отправлять так много параметров и все заработало. Причем заработало чуть-ли не всеми способами, предложенными здесь!  smile 
Глюки проявляли себя так:
Когда я передавал размер стрима в виде параметра, файл нормально принимался, но потом не открывался, потому что в него, зачем-то, в начало записывались 2 каких-то байта, вместо 2-х нулевых в конце. Если удалить их то файл открывается.
Когда передаешь размер стрима WriteInteger(stream.size), то на приеме (sz:=ReadInteger) sz равняется всегда 218772273. 
Получается, что лучше передавать что-либо не через параметры, а так, Writ'ом.  smile 

Всем спасибо!!!  smile  
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0613 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.