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

Вниз

Как по UDP (используя Indy) передать файл поблочно.   Найти похожие ветки 

 
freak   (2004-05-08 19:19) [0]

Привет всем мастерам!

Вопрос такой как по UDP (используя Indy) передать файл поблочно. Вернее проблема в том как его получить.
Не хочу использовать всякие там TMemoryStream или TFileStrem. Что если кому-то взбредет в голову отправить файлик размером этак мегабайт 700, в таком случае оперативке конец. Лучше считывать файл блоками и отправлять их.

Вот здесь листинг клиента и сервера. Отправляем IdUDPClient’ом файлик и на удаленной машине получаем IdUDPServer’ом. Клиент отсылает файл полностью, но сервер принимает его не до конца и не посылает ответ, что файл принят. Где я ошибся не могу понять. Помогите уважаемые мастера разобртся.

Часть кода написана по материалам, опубликованным на этом сайте.

{ЛИСТИНГ КЛИЕНТА (посылаем файл)}
procedure TForm1.Button2Click(Sender: TObject);
var FromF: file;
   NumRead: Integer;
   Buf: array[1..2048] of Char;
   EndPrisnak: String;
   Count: Integer;
begin
UDPClient.Port := 3030;
UDPClient.Host := "192.168.0.1";
UDPClient.Active := True;

AssignFile(FromF, Edit1.Text);
Reset(FromF, 1);

{перед отправкой файла, посылаем удаленной машине команду-предупреждение, что сейчас будем пересылать файл. Команда содержит имя и размер файла}
UDPClient.Send("file#"+Edit1.Text+"#"+IntToStr(FileSize(FromF))+"#");
{Ждем секунду, пока удаленная машина переходит в режим приема файла, хотя этого можно и не делать}
Sleep(1000);

{Передаем файл}
while FilePos(FromF) <> FileSize(FromF) do
begin
  BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
  UDPClient.SendBuffer(Buf, SizeOf(Buf));
  Label1.Caption := "Отправленно " + IntToStr(FilePos(FromF)) + " из " + IntToStr(FileSize(FromF));
  ProgressBar1.Position := FilePos(FromF) * 100 div FileSize(FromF);
end;  

{После передачи, ждем определенный промежуток времени, пока удаленная машина скажет нам, что прием файла закончен. Время ожидания задается в свойстве IdUDPClient.ReciveTimeout. Если мы не получим ответ “end”, то считаем, что файл не принят}
UDPClient.ReceiveBuffer(EndPrisnak, SizeOf(EndPrisnak));
 if EndPrisnak <> "end" then
  ShowMessage(‘Прием файла на удаленной машине прошел не удачно.’)
 else
  CloseFile(FromF);

end;

{ЛИСТИНГ СЕРВЕРА (Принимаем файл)}

 private
   { Private declarations }
  Name: string;
  Size: integer;
  Receive: boolean;
  ToF: file;
  NumWritten: Integer;

procedure TForm1.FormCreate(Sender: TObject);
begin
UDPServer.Active:=True;
Receive := false;
end;

procedure TForm1.Writing(AData: TStream; ABinding: TIdSocketHandle);
var s:String;
begin
if FilePos(ToF) < Size then
BlockWrite(ToF, AData, AData.Size, NumWritten);
ProgressBar1.Position := FilePos(ToF)*100 div Size;
Label3.Caption := "Принято " + IntToStr(FilePos(ToF)) + " из " + IntToStr(Size);
Label4.Caption := "Размер блока: "+IntToStr(AData.Size);

if FilePos(ToF) = Size then
begin
Receive := false;
CloseFile(ToF);
s := "end";
ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, s[1], Length(s));
end;
end;

procedure TForm1.UDPServerUDPRead(Sender: TObject; AData: TStream;
 ABinding: TIdSocketHandle);
var Rtext: string; // ???????? ?????
    DataStringStream: TStringStream;
begin
 if Receive then
   Writing(AData, ABinding)

 else
  DataStringStream := TStringStream.Create("");
  DataStringStream.CopyFrom(AData, AData.Size);
  Rtext := DataStringStream.DataString;
  DataStringStream.Free;
  if Copy(Rtext, 0, Pos("#", Rtext) -1)  =  "file" then
    begin
      Delete(Rtext, 1, Pos("#", Rtext));
      Name := ExtractFileName(Copy(Rtext, 0, Pos("#", Rtext) -1));
      Delete(Rtext, 1, Pos("#", Rtext));
      Size := StrToInt(Copy(Rtext, 0, Pos("#", Rtext) -1));
      Delete(Rtext, 1, Pos("#", Rtext));
      Label1.Caption := ‘Размер файла: ‘ + IntToStr(Size) + " байт";
      Label2.Caption := "Имя файла: " + Name;
      AssignFile(ToF, "C:\" + Name);
      Rewrite(ToF, 1);
      Receive := true;
      Writing(AData, ABinding);
    end;

end;


 
Rouse_ ©   (2004-05-08 20:09) [1]

Код не разбирал...
Не желательно передавать данные которые должны быть приняты полностью (в отличие к примеру от звуковых потоков) без искажений при помощи UDP...
Именно для этого есть другие протоколы...


 
freak   (2004-05-09 01:51) [2]

UDP - это принципиально важно. Не могу использовать другой протокол. Тем более если использовать TMemoryStream или TFileStrem то передача проходит нормально. Проблеммы возникают правда если передоваемый файл больше размера буфера IdUDPClient/Server. Но как  уже говорил всякие Stream"ы мне не подходят.


 
Anatoly Podgoretsky ©   (2004-05-09 12:22) [3]

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



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

Форум: "Сети";
Текущий архив: 2004.07.04;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.46 MB
Время: 0.076 c
1-1087926704
HF-Trade
2004-06-22 21:51
2004.07.04
Film.Transparent:=True;


14-1087325194
XIII
2004-06-15 22:46
2004.07.04
Проблемка


4-1085223150
Jel
2004-05-22 14:52
2004.07.04
Работа с ExtractIconEx - есть вопросы


1-1087198507
Yakudza
2004-06-14 11:35
2004.07.04
Ошибка при закрытии программы


8-1082600639
Boson
2004-04-22 06:23
2004.07.04
Фильтр НЧ





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский