Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.08.30;
Скачать: CL | DM;

Вниз

IdTCPClient1+IdTCPserver1 передача - получение файла   Найти похожие ветки 

 
Varkan   (2009-07-02 12:17) [0]

Необходимо с помощью программы сервера раздать файл по сети для программ клиентов. В сети может около 20-30 одновременных соединений.  Использую для клиента такой кусочек кода:
try
vixid:=False;
repeat
IdTCPClient1.Connect(); //соединяюсь
try
 RichEdit1.Lines.Add("Начал "+TimeToStr(now));
 IdTCPClient1.WriteLn("Fail");
 GetMem(FileName, 256);
 try
   IdTCPClient1.ReadBuffer(FileName^, 256);
   IdTCPClient1.ReadBuffer(FileSize, SizeOf(FileSize));
   FS := TFileStream.Create(ExtractFilePath(Application.ExeName)+FileName, fmCreate);
// тут создается файл в папке с программой
   try
     IdTCPClient1.ReadStream(FS, FileSize);//получаю файл
   finally
     FS.Free;
   end;
 finally
   FreeMem(FileName);
 end;
 IdTCPClient1.WriteLn("otrimav");//шлю серверу что все вери гуд
 IdTCPClient1.Disconnect;
 vixid:=true;
 RichEdit1.Lines.Add("Закончил "+TimeToStr(now));
 except
 IdTCPClient1.Disconnect;
 RichEdit1.Lines.Add("Не передал "+TimeToStr(now));
 end;
until vixid;
except
RichEdit1.Lines.Add("Не удалось присоиденится к серверу "+TimeToStr(now));
end;

Если файл небольшого размера(~20-30 Мб) то он нормально получается. Но если файл побольше будет то программа-клиент его не получает.

В сервере код передачи файла выглядит у меня так:
 s:=AThread.Connection.ReadLn();
 if s="Fail" then
 try
  s:=AThread.Connection.Socket.Binding.PeerIP;
 FileToSend := Edit1.Text;  // тут файл, который мы рассылаем компу клиенту.
 with TFileStream.Create(FileToSend, fmOpenRead) do
 try
   FileToSend := ExtractFileName(FileToSend) + #00;
   GetMem(p, 256);
   try
     CopyMemory(p, @FileToSend[1], Length(FileToSend));
     AThread.Connection.Socket.Send(p^, 256);
   finally
     FreeMem(p);
   end;
     FileSize := Size;
     AThread.Connection.Socket.Send(FileSize, SizeOf(FileSize));
     GetMem(p, Size);
   try
     ReadBuffer(p^, Size);
     AThread.Connection.Socket.Send(p^, Size);
   finally
     FreeMem(p);
   end;
 finally
   Free;
 end;
 s:=AThread.Connection.ReadLn();
 except
//  RichEdit1.Lines.Add("Не смог передать файл на "+s+" "+TimeToStr(now));
 end;
 AThread.Connection.Disconnect;

P.S.  Помогите пожалуйста решить данную проблему. Надо сделать так чтоб б с 99,9% вероятностью файл передался на клиенты, когда сеть на 100% исправна.
Кстати подозреваю что нада исходный файл передавать по частях, а не весь сразу. Но как ето реализовать не могу понять.(но может я не прав)


 
Сергей М. ©   (2009-07-02 12:39) [1]

К чему эти пляски с промежуточным буфером p ?

Для приема/передачи текстовой строки, содержащей имя файла, есть метод Connection.IOHandler.Read/WriteLn, а для приема/передачи стрима - Connection.IOHandler.Read/WriteStream

Можно и без стрима при передаче обойтись, благо есть метод Connection.IOHandler.WriteFile, но перед этим следует передать размер файла методом Connection.IOHandler.Write


 
Anatoly Podgoretsky ©   (2009-07-02 12:54) [2]

По смыслу больше похоже на ФТП


 
Varkan   (2009-07-02 14:48) [3]

Уважаемый Сергей М. че то я не вижу у IOHandler всех тех методов (Read/WriteLn, Connection.IOHandler.WriteFile). А не могли бы Вы показать часть кода передачи/приема файла. Есть Connection.WriteFile.

> но перед этим следует передать размер файла методом

Вообще ... зачнм передавать размер файла предварительно? Что бы сравнить в конце передачи  и дать ответ передан он полностю или нет?


> По смыслу больше похоже на ФТП

То есть Вы предлагаете пробовать копать по созданию ФТП сервера?


 
Сергей М. ©   (2009-07-02 14:53) [4]


> че то я не вижу у IOHandler всех тех методов


Я веду речь об Indy10, там они есть.
И тебе настоятельно рекомендую обновиться до 10-ки.
А где ты собссно ищешь эти методы - в справке или в исходниках ?


 
Varkan   (2009-07-02 17:32) [5]


> А где ты собссно ищешь эти методы - в справке или в исходниках
> ?

посмотрел в справке


 
Сергей М. ©   (2009-07-02 19:57) [6]

Справка индейская - неважнецкая..
Ныряй в исходники


 
Varkan   (2009-07-02 20:13) [7]


> Справка индейская - неважнецкая..
> Ныряй в исходники

Ну а ваще стоит заниматся IdTCPClient1+IdTCPserver1, или перейти и пробовать юзать IdFTP1 и IdFTPServer1 (никогда с ними не работал и даже не подозреваю как)?


 
Сергей М. ©   (2009-07-02 20:16) [8]

Не стОит, если кроме как файловыми операциями твои клиенты и твой сервер не озабочены


 
Varkan   (2009-07-02 21:04) [9]

Хорошо, допустим сервер посылает на запрос клиента размер файла и сам файл Connection.WriteFile. Тогда я непонимаю как обрабатывать на клиенте ету передачу. Почему нету IdTCPClient1.readlnFile? Или все же IdTCPClient1.ReadStream нада будет обходится?


 
Сергей М. ©   (2009-07-02 21:54) [10]


> Или все же IdTCPClient1.ReadStream нада будет обходится?


Да, вполне достаточно, если передатчик непосредственно перед вызовом WriteFile выполнит передачу размера этого файла (Int64)


 
Varkan   (2009-07-02 22:37) [11]


> Да, вполне достаточно

Так, а почему в моем  примере передачи-получения файла именно на IdTCPClient1.ReadStream(FS, FileSize);//получаю файл
происходит не получение файла, если он большого размера. Или здесь проблемы с  
ReadBuffer(p^, Size);
AThread.Connection.Socket.Send(p^, Size);


 
Varkan   (2009-07-02 23:37) [12]

Уважаемый Сергей М. большое Вам спасибо за помощь ...
Сейчас месяц-два у меня наверное не будет возможности протестить передачу файла по сети, но передача файла на одном компе происходит, и при етом мой вариант что написан выше, файлы даже на одном компе размером больше 80 мб. не передавал, а с Вашей помощью у меня получилося передать 500 мб. Надеюсь при использовании 20-30 компов еект будет тот же. Для начинающих и тех кто ищет как ето можно сделать напишу код передачи файла от сервера к клиету:
Клиент:

try
IdTCPClient1.Connect();
s:=IdTCPClient1.ReadLn();
file_name:=IdTCPClient1.ReadLn();
FS := TFileStream.Create(ExtractFilePath(Application.ExeName)+file_name, fmCreate);

  try
  try
    IdTCPClient1.ReadStream(FS, StrToInt64(s));
  finally
    FS.Free;
  end;
  except
 ShowMessage("Не получил");
  end;

IdTCPClient1.Disconnect;
except
ShowMessage("Не соиденился");
end;


сервер:

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
begin
AThread.Connection.WriteLn(Label1.Caption);
AThread.Connection.WriteLn(ExtractFileName(Edit1.Text));
AThread.Connection.WriteFile(Edit1.Text);
AThread.Connection.Disconnect;
end;


Если че не так написал, скажите. Может тут где то есть какие то подводные камни?
P.S. Уважаемый Сергей М. с меня пивко при встрече :)))


 
Сергей М. ©   (2009-07-03 08:32) [13]


> Может тут где то есть какие то подводные камни?


Да не то чтобы подводные, но ..

АП ведь правильно намекнул: к чему этот самодельный велосипед, если фактически тоже самое делается готовым FTP-инструментарием - TIdFTP/TIdFTPServer ?


 
Anatoly Podgoretsky ©   (2009-07-03 08:56) [14]

> Сергей М.  (03.07.2009 08:32:13)  [13]

С возможностью докачки и долбежки.


 
Varkan   (2009-07-03 08:56) [15]


>  готовым FTP-инструментарием - TIdFTP/TIdFTPServer ?

Нада тогда смотреть ети компоненты и разбиратся с ними. На даный момент меня удовлетворяет последнее решение. Причем ета программа будет передавать не только даные файла, но и текстовую информацию (string).
спс. Сергей М.
спс. Anatoly Podgoretsky
Можна закрывать обсуждение.



Страницы: 1 вся ветка

Текущий архив: 2009.08.30;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.016 c
15-1246431478
pasha_golub
2009-07-01 10:57
2009.08.30
Как вызвать стандартный property editor для свойства?


1-1211873321
ыы
2008-05-27 11:28
2009.08.30
Delphi & FineReader


15-1246566925
Юрий
2009-07-03 00:35
2009.08.30
С днем рождения ! 3 июля 2009 пятница


1-1212668728
Sha
2008-06-05 16:25
2009.08.30
Насколько адекватен SizeOf


2-1246624890
Художник
2009-07-03 16:41
2009.08.30
Сброс размера динамического массива