Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Файл через сокеты


Автор: NOD 28.2.2004, 02:13
Простите конечно...
ФАК я закачал и неашел там опятть такую же статью по этому поводу...
В примере закачивается только содержимое имэйджа, а мнея интересует именно файл...
Наверное я опять сам натупил, но никак не выходит...
Если кому не влом помогите, переделайте его под конкретный файл. thumbs-up.gif

Автор: Vex 28.2.2004, 02:31

Код



unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 ScktComp, ExtCtrls, StdCtrls;

type
 TForm1 = class(TForm)
   Image1: TImage;
   Image2: TImage;
   ClientSocket1: TClientSocket;
   ServerSocket1: TServerSocket;
   Button1: TButton;
   procedure Image1Click(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure ClientSocket1Connect(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure ServerSocket1ClientRead(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
 private
   { Private declarations }
   Reciving: boolean;
   DataSize: integer;
   Data: TMemoryStream;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Image1Click(Sender: TObject);
begin
 // Это процедура для открытия сокета на ПРИЁМ (RECEIVING).
 // Button1.Click is this procedure as well.
 ClientSocket1.Active:= true;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 // Открытие ОТПРАВЛЯЮЩЕГО (SENDING) сокета.
 ServerSocket1.Active:= true;
end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
 Socket: TCustomWinSocket);
begin
 // Посылаем команду для начала передачи файла.
 Socket.SendText('send');
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
 Socket: TCustomWinSocket);
var
 s, sl: string;
begin
 s:= Socket.ReceiveText;
 // Если мы не в режиме приёма:
 if not Reciving then
 begin
   // Теперь нам необходимо получить длину потока данных.
   SetLength(sl, StrLen(PChar(s))+1); // +1 for the null terminator
   StrLCopy(@sl[1], PChar(s), Length(sl)-1);
   DataSize:= StrToInt(sl);
   Data:= TMemoryStream.Create;
   // Удаляем информацию о размере из данных.
   Delete(s, 1, Length(sl));
   Reciving:= true;
 end;
 // Сохраняем данные в файл, до тех пор, пока не получим все данные.
 try
   Data.Write(s[1], length(s));
   if Data.Size = DataSize then
   begin
     Data.Position:= 0;
     Image2.Picture.Bitmap.LoadFromStream(Data);
     Data.Free;
     Reciving:= false;
     Socket.Close;
   end;
 except
   Data.Free;
 end;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
 Socket: TCustomWinSocket);
var
 ms: TMemoryStream;
begin
 // Клиент получает команду на передачу файла.
 if Socket.ReceiveText = 'send' then
 begin
   ms:= TMemoryStream.Create;
   try
     // Получаем данные на передачу.
     Image1.Picture.Bitmap.SaveToStream(ms);
     ms.Position:= 0;
     // Добавляем длину данных, чтобы клиент знал, сколько данных будет
     // передано. Добавляем #0 , чтобы можно было определить, где
     // заканчивается информация о размере.
     Socket.SendText(IntToStr(ms.Size) + #0);
     // Посылаем его.
     Socket.SendStream(ms);
   except
     // Итак, осталось освободить поток, если что-то не так.
     ms.Free;
   end;
 end;
end;

end.


Автор: M K
www.sources.ru

Автор: NOD 28.2.2004, 02:38
Да, да... именно этот пример я уже находил на 3 сайтах
Вот я попросил подсказать как его переделать чтоб качать конкретный файл, а не картинку из Image

Автор: Vex 28.2.2004, 02:53
Код

var
ms: TMemoryStream;
begin
ms:= TmemoryStream.Create;
ms.LoadFromFile(твой файл);


...

Автор: NOD 28.2.2004, 02:59
А через tFileStream никак не получится?

Автор: dm9 28.2.2004, 15:47
Насчёт TFileStream не скажу (можно самому попробовать...)

А вот насчёт кода сделаю одно уточнение. Кажется, в последней процедуре надо except заменить на finally, а то утечка памяти...

Автор: Гость_Вася 29.2.2004, 11:33
Я когда-то использовал TFileStream.
приблизительно это выглядело так:

посылаем:

buf: array[1..1024] of Char;
i: Integer;
f: TFileStream;

f := TFileStream.Create('File.exe', fmOpenRead);
while f.Pos < f.Size do begin
i := f.ReadBuffer(buf, 1024);
socket.SendBuf(buf, i);
end;

получаем:

buf: array[1..1024] of Char;
i: Integer;
f: TFileStream;

f := TFileStream.Create('File.exe', fmOpenWrite);
i := socket.ReceiveBuf(buf, 1024);
f.WriteBuffer(buf, i);

Тут надо еще передовать (например, в первом или последнем байте) команду, при которой удаленная программа будет знать, что ей делать, запись в файл или подготовка к записи и т.д.






Автор: NOD 2.3.2004, 05:01
вроде разобрался

Автор: NOD 2.3.2004, 05:07
Цитата

f := TFileStream.Create('File.exe', fmOpenWrite);
i := socket.ReceiveBuf(buf, 1024);
f.WriteBuffer(buf, i);


Здесь наверное не до конца написано....
Без цикла....

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)