Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Послать файл от TServerSocket на TClientSocket

Delphi , Интернет и Сети , Файлы и Интернет

Послать файл от TServerSocket на TClientSocket

Мой адрес на дом и не улица, мой адрес тройной дабл ю.


unit Unit1; 

interface 

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

type 
  TForm1 = class(TForm) 
    ClientSocket1: TClientSocket; 
    ServerSocket1: TServerSocket; 
    btnTestSockets: TButton; 
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    procedure ClientSocket1Disconnect(Sender: TObject; 
      Socket: TCustomWinSocket); 
    procedure ClientSocket1Connect(Sender: TObject; 
      Socket: TCustomWinSocket); 
    procedure ServerSocket1ClientConnect(Sender: TObject; 
      Socket: TCustomWinSocket); 
    procedure btnTestSocketsClick(Sender: TObject); 
  private 
    FStream: TFileStream; 
    { Private-Deklarationen } 
  public 
    { Public-Deklarationen } 
  end; 

var 
  Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.ClientSocket1Read(Sender: TObject; 
  Socket: TCustomWinSocket); 
var 
  iLen: Integer; 
  Bfr: Pointer; 
begin 
  iLen := Socket.ReceiveLength; 
  GetMem(Bfr, iLen); 
  try 
    Socket.ReceiveBuf(Bfr^, iLen); 
    FStream.Write(Bfr^, iLen); 
  finally 
    FreeMem(Bfr); 
  end; 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
  FStream := nil; 
end; 

procedure TForm1.FormDestroy(Sender: TObject); 
begin 
  if Assigned(FStream) then 
  begin 
    FStream.Free; 
    FStream := nil; 
  end; 
end; 

procedure TForm1.ClientSocket1Disconnect(Sender: TObject; 
  Socket: TCustomWinSocket); 
begin 
  if Assigned(FStream) then 
  begin 
    FStream.Free; 
    FStream := nil; 
  end; 
end; 

procedure TForm1.ClientSocket1Connect(Sender: TObject; 
  Socket: TCustomWinSocket); 
begin 
  FStream := TFileStream.Create('c:\temp\test.stream.html', fmCreate or fmShareDenyWrite); 
end; 

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; 
  Socket: TCustomWinSocket); 
begin 
  Socket.SendStream(TFileStream.Create('c:\temp\test.html', fmOpenRead or fmShareDenyWrite)); 
end; 

procedure TForm1.btnTestSocketsClick(Sender: TObject); 
begin 
  ServerSocket1.Active := True; 
  ClientSocket1.Active := True; 
end; 

end.

Перевод контента на русский язык:

Программа написана на Delphi и представляет собой простое приложение клиент-сервер с использованием сокетов. Сокет сервера (ServerSocket1) слушает входящие соединения, и когда соединение установлено, он отправляет содержимое файла ('c:\temp\test.html') клиенту.

Вот некоторые вещи, которые можно улучшить:

  • В процедуре ClientSocket1Read вы читаете данные из сокета, записываете их в поток (FStream) и затем освобождаете память. Но что если клиент отключится, когда еще есть данные, которые пишутся в файл? Нужно добавить проверку ошибок для обработки этой ситуации.
  • Процедура FormCreate только инициализирует FStream в nil. Лучше было бы освободить любые существующие потоки перед инициализацией нового.
  • В процедурах ClientSocket1Disconnect и FormDestroy вы освобождаете FStream, но что если он не был назначен? Нужно добавить проверку ошибок для этого.
  • Путь к файлу 'c:\temp\test.stream.html' жестко закодирован. Лучше было бы сделать это настройкой или использовать более надежный способ указания пути к файлу.
  • При отправке файла с сервера вы используете метод SendStream, который отправляет файл в блоки. Это может привести к проблемам, если клиент не прочитает все данные перед отключением. Более надежным способом было бы отправить длину файла первым и затем фактические данные.

В этом решении я убрал процедуру ClientSocket1Connect, так как она не нужна. В процедуре ServerSocket1ClientConnect я отправляю размер файла первым, а затем фактические данные. Так клиент может знать, сколько данных ожидать, перед тем как прочитать из сокета.

procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
var
  iLen: Integer;
  Buf: Pointer;
begin
  if not Assigned(FStream) then Exit;

  iLen := FStream.Size;
  GetMem(Buf, iLen);
  try
    FStream.Position := 0;
    FStream.Read(Buf^, iLen);
    Socket.SendBuf(Buf^, iLen);
  finally
    FreeMem(Buf);
  end;
end;

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
var
  FileSize: Integer;
begin
  FStream := TFileStream.Create('c:\temp\test.html', fmOpenRead or fmShareDenyWrite);
  try
    FileSize := FStream.Size;
    Socket.SendBuf(PChar(IntToHex(FileSize, 8)), 8); // Send the file size as a string
    FStream.Position := 0;
    Socket.SendBuf(FStream.Memory^, FileSize); // Send the actual file data
  finally
    FStream.Free;
  end;
end;

procedure TForm1.btnTestSocketsClick(Sender: TObject);
begin
  ServerSocket1.Active := True;
  ClientSocket1.Active := True;
end;

В статье рассматривается пример использования библиотеки ScktComp в Delphi для отправки файла от серверного сокета на клиентский с помощью метода SendStream.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Файлы и Интернет ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-01 11:15:15/0.0056099891662598/1