Страница 1 из 3

передача файлов по сети

Добавлено: 05 окт 2005, 21:57
Саша
Подскажите пожайлуста с передачей файлов!! Я только начинаю программировать и у меня задача в передаче файлов из одной машины допустим на другую с каким нибудь айпи адресом. Как это можно организовать в Дельфи 7?

Добавлено: 06 окт 2005, 08:16
LAngel
Есть много способов снять шкуру с кота :) )
самый простой - воспользоваться системной функцией копирования и скопировать файл в \\comp\share\filename.ext :)
если на обоих компах запускать программы - тогда можно написать клиент-сервер tcp и перегнать файл вручную...
А есть ещё ftp, http...

Если какой-нить вариант заинтересовал - могу рассказать подробнее.

Добавлено: 06 окт 2005, 09:40
Саша
LAngel писал(а):Есть много способов снять шкуру с кота :) )
самый простой - воспользоваться системной функцией копирования и скопировать файл в \\comp\share\filename.ext :)
если на обоих компах запускать программы - тогда можно написать клиент-сервер tcp и перегнать файл вручную...
А есть ещё ftp, http...

Если какой-нить вариант заинтересовал - могу рассказать подробнее.
Я думаю что лучше бы было через клиент-сервер так как копирование нужно сделать допустим сразу на 10 компов в сети

Добавлено: 06 окт 2005, 11:21
LAngel
самое простое - это с помощью
IdTCPServer...

Сначала надо определиться с форматом передачи данных.
Пусть у нас сначала будет передаваться имя файла, в формате pchar (c замыкающим нулем) длинной 256 байт.
Потом передается размер файла. целое число типа Cardinal (DWORD)
Потом поток данных самого файла.

Создаем новую форму, кладем на неё IdTCPServer, в строке bind указываем, какие адреса и порты он будет "слушать".
Ставим ему Active := True (пусть работает все время, когда программа запущена). И в Events на onConnect пишем следующее:

Код: Выделить всё

procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
var
  FileToSend: String;
  FileSize: Cardinal;
  p: Pointer;
begin
  FileToSend := 'c:\MSDOS.SYS';  // тут файл, который мы рассылаем любому попросившему.
  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;
  AThread.Connection.Disconnect;
  ShowMessage('Послано');
end;
Ну все... сервер готов.

Теперь клиента:

Тоже самое. Форма, на форме IdTCPClient, свойство Port указываем такое же, что и в bind сервера. host = ip адрес машины, на которой стоит сервер. (127.0.0.1 для локального компа), Кладем ещё кнопочку и при нажатии кнопки делаем:
IdTCPClient1.Connect;

В обработчике (Events) onConnected пишем следующее:

Код: Выделить всё

procedure TForm1.IdTCPClient1Connected(Sender: TObject);
var
  FileName: PChar;
  FileSize: Cardinal;
  FS: TFileStream;
begin
  GetMem(FileName, 256);
  try
    IdTCPClient1.ReadBuffer(FileName^, 256);
    IdTCPClient1.ReadBuffer(FileSize, SizeOf(FileSize));
    FS := TFileStream.Create('incoming\'+FileName, fmCreate); // тут создается файл, я его положил в каталог incoming
    try
      IdTCPClient1.ReadStream(FS, FileSize);
    finally
      FS.Free;
    end;
  finally
    FreeMem(FileName);
  end;
  ShowMessage('Принято');
end;
Ну вот и все... простейший клиент-сервет на инди функционирует...

Добавлено: 06 окт 2005, 16:09
drmist
Саша
Читайте про сокеты.

Добавлено: 06 окт 2005, 22:11
Саша
LAngel писал(а):самое простое - это с помощью
IdTCPServer...

Сначала надо определиться с форматом передачи данных.
Пусть у нас сначала будет передаваться имя файла, в формате pchar (c замыкающим нулем) длинной 256 байт.
Потом передается размер файла. целое число типа Cardinal (DWORD)
Потом поток данных самого файла.

Создаем новую форму, кладем на неё IdTCPServer, в строке bind указываем, какие адреса и порты он будет "слушать".
Ставим ему Active := True (пусть работает все время, когда программа запущена). И в Events на onConnect пишем следующее:

Код: Выделить всё

procedure TForm1.IdTCPServer1Connect&#40]

Ну все... сервер готов.

Теперь клиента:

Тоже самое. Форма, на форме IdTCPClient, свойство Port указываем такое же, что и в bind сервера. host = ip адрес машины, на которой стоит сервер. (127.0.0.1 для локального компа), Кладем ещё кнопочку и при нажатии кнопки делаем:
  IdTCPClient1.Connect;

В обработчике (Events) onConnected пишем следующее:
[code]
procedure TForm1.IdTCPClient1Connected(Sender: TObject);
var
  FileName: PChar;
  FileSize: Cardinal;
  FS: TFileStream;
begin
  GetMem(FileName, 256);
  try
    IdTCPClient1.ReadBuffer(FileName^, 256);
    IdTCPClient1.ReadBuffer(FileSize, SizeOf(FileSize));
    FS := TFileStream.Create('incoming\'+FileName, fmCreate); // тут создается файл, я его положил в каталог incoming
    try
      IdTCPClient1.ReadStream(FS, FileSize);
    finally
      FS.Free;
    end;
  finally
    FreeMem(FileName);
  end;
  ShowMessage('Принято');
end;
Ну вот и все... простейший клиент-сервет на инди функционирует...
Спасибо ОГРОМНЕЙШЕЕ! Всё работает! Я разобрался как и что нужно изменить что бы передать из нужной мне папки на сервере на 4 клиентские машины!!
Но сами понимаете что охота разобратся во всем поподробнее!! Что можете посоветовать для прочтения, что бы можно было разобратся в этих процедурах поподробнее?? мне тут подсказали что нужно почитать про сокеты? Вы неподскажите какой либо доступный источник где можно это прочесть, так как я никогда неработал с файлами и с сетью в дельфи... Весьма благодарен за Вашу помощь! :)

Добавлено: 26 окт 2005, 10:34
Dr_Grizzly
Парни у меня проблема возникла!
Ругается на строку:

Код: Выделить всё

AThread.Connection.socket.Send(p^, 256);
Говорит что Undeclared Identifier "Socket"

Что я не так сделал????

Добавлено: 26 окт 2005, 12:23
Dr_Grizzly
Есть еще проблема, я заремарил всю эту процедуру. Задал в binding
ip адрес одной из машины в сети на которой будет клиетнская часть, и указал 20 порт, ну как я думаю можно ведь любой порт указать, хоть 5000? Потом задал свойство active=true, запустил прогу, а она сказал Socket Error # 10049 что еще нужно было сделать? Или что я не так сделал???

Добавлено: 26 окт 2005, 18:38
Zroman
А фаервол на винде отключен? В ХР он есть и мешает жить программистам, работающим с сетью.

Добавлено: 27 окт 2005, 07:39
Dr_Grizzly
Конечно отключен :) Мне эта зараза сразу мешала жить :D