Я к вам, господа, и вот по какому вопросу:
Возникла необходимость написания софтинки для передачи файлов в локальной сети.
Помучав гугль и полистав соответствующую литературу, остановился на Indy 9 IdTcpServer и IdTcpClient. Сервер включен и слушает порт, клиент время от времени передает определенные файлы. Методом проб и ошибок сварганил более - менее рабочий вариант. В процессе тестирования обнаружился один неприятный подвох - большие файлы, размером в несколько сотен Мб передаваться категорически отказываются, на стороне сервера создается файл 0 байт.
Короче говоря - пришел к выводу, что файл лучше передавать кусками, попробовал все это дело реализовать - ан нет, моих скромных познаний в этой области оказалось недостаточно. Перепробовал несколько вариантов - не то. Файл создается, что - то в него записывается, но размер в итоге отличается от оригинала.
Как я это вижу:
Клиент - файл загружается в FileStream, размер файла делится на размер блока(допустим 1000 байт) = получаем количество блоков. Отправляем на сервер количество блоков или размер файла. В цикле отправляем блоки, увеличивая с каждым проходом FileStream.Position на соответствующее значение.
Сервер - создаем FileStream, опять же в цикле записываем полученые от клиента блоки в какой - то промежуточный буфер, копируем в FIleStream (например FS.CopyFrom(...)). По получению последнего блока или достижению FS определенного размера выходим из цикла.
В общем буду весьма и весьма признателен за помощь в реализации всего этого безобразия. Ниже приведен код, который работает на данный момент и нуждается в доработке.
З.Ы. Я не студент, в армию не отправляйте.
Код:
...
Server: TIdTCPServer;
Client: TIdTCPClient;
...
procedure TForm1.Button1Click(Sender: TObject);
var
FileName : String;
FileSize : Cardinal;
p : Pointer;
begin
Client.Connect();
FileName := 'C:\1.rar';
with TFileStream.Create(FileName, fmOpenRead) do
try
FileName := ExtractFileName(FileName) + #00;
GetMem(p, 256);
try
CopyMemory(p, @FileName[1], Length(FileName));
Client.Socket.Send(p^, 256);
finally
FreeMem(p);
end;
FileSize := Size;
Client.Socket.Send(FileSize, SizeOf(FileSize));
GetMem(p, Size);
try
ReadBuffer(p^, Size);
Client.Socket.Send(p^, Size);
finally
FreeMem(p);
end;
finally
Free;
end;
Client.Disconnect;
end;
procedure TForm1.ServerExecute(AThread: TIdPeerThread);
var
FileName : PChar;
FileSize : Cardinal;
FS : TFileStream;
begin
GetMem(FileName, 256);
try
Athread.Connection.ReadBuffer(FileName^, 256);
Athread.Connection.ReadBuffer(FileSize, SizeOf(FileSize));
FS := TFileStream.Create(FileName, fmCreate);
try
aThread.Connection.ReadStream(FS, FileSize);
finally
FS.Free;
end;
finally
FreeMem(FileName);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Server.Active := true;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Server.Active := false;
end;