Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.08.30;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.005 c
2-1246026729
Vayrus
2009-06-26 18:32
2009.08.30
Проблема с GetKeyDateTime в Win XP


2-1246461858
Zheksonz
2009-07-01 19:24
2009.08.30
strn:=#01#06#00#04#19#136;


15-1246195055
Юрий
2009-06-28 17:17
2009.08.30
С днем рождения ! 28 июня 2009 воскресенье


2-1246604370
Neket
2009-07-03 10:59
2009.08.30
Как узнать колличество записей в DBGrid?


15-1245952925
Nodt
2009-06-25 22:02
2009.08.30
Поиск работы.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский