Форум: "Начинающим";
Текущий архив: 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.006 c