Delphi Can
Thread Socket (Yardım) - Baskı Önizleme

+- Delphi Can (https://www.delphican.com)
+-- Forum: Delphi (https://www.delphican.com/forumdisplay.php?fid=3)
+--- Forum: Genel Programlama (https://www.delphican.com/forumdisplay.php?fid=6)
+--- Konu Başlığı: Thread Socket (Yardım) (/showthread.php?tid=4769)



Thread Socket (Yardım) - hkeskin - 27-04-2020

İyi günler öncelikle 
Socketi Thread içerisinde kullanıyorum fakat thread çalışıyor ClientSocketde öyle bağlanıyor ama hemen arkasından sanırım thread ta kapanıyor Sockette yardımcı olabilecek varmı?
unit unit2;

interface

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

type
 TClientSockThread = class(TThread)
 private
   fIp: string;
   fClientSocket: TClientSocket;
   procedure ClntConnect(Sender: TObject; Socket: TCustomWinSocket);
 protected
   procedure DoTerminate; override;
   procedure Execute; override;
   procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
   procedure ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);

   property Clnt: TClientSocket read fClientSocket write fClientSocket;

 private
   FStream: TFileStream;

 public
   constructor Create(Ip: string);
 end;

 TForm2 = class(TForm)
   Button1: TButton;
   Memo1: TMemo;
   procedure Button1Click(Sender: TObject);
 private

 public
   { Public declarations }
 end;

var
 Form2: TForm2;

implementation

{$R *.DFM}

procedure TClientSockThread.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
var
iLen: Integer;
Bfr: Pointer;
begin
     FStream := TFileStream.Create('C:\Users\hkesk\Desktop\XxXxXx\Win32\Debug\down\somine.mkv', fmCreate or fmShareDenyWrite);
     iLen := Socket.ReceiveLength;
     GetMem(Bfr, iLen);
         try
             Socket.ReceiveBuf(Bfr^, iLen);
             FStream.Write(Bfr^, iLen);
         finally
             FreeMem(Bfr);
         end;
end;

procedure TForm2.Button1Click(Sender: TObject);
var
 i: Integer;
begin
   TClientSockThread.Create('127.0.0.1');
end;

{ TClientSockThread }

procedure TClientSockThread.ClntConnect(Sender: TObject; Socket:
 TCustomWinSocket);
begin
 //formdaki memo yada liste kutusuna baglı olanı ekle
 Form2.Memo1.Lines.Add(Socket.RemoteAddress+' | '+Socket.RemoteHost);
end;

constructor TClientSockThread.Create(Ip: string);
begin
 inherited Create(False);
 fIp := Ip;
 //thread kapanırken kendini sonlandırır.
 //bu ozellik bu gibi durumlarda cok ise yaramakta
FreeOnTerminate := True;
end;

procedure TClientSockThread.DoTerminate;
begin
 //thread sonlanırken clientsocket nesnesi yokedilir.
 fClientSocket.Free;
 inherited DoTerminate;
end;

procedure TClientSockThread.ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);
var
 I: Integer;
begin
   Form2.Memo1.Lines.Add('Çıktı..');
end;

procedure TClientSockThread.Execute;
begin
 //socket create edilir.
 fClientSocket := TClientSocket.Create(nil);

 with fClientSocket do
 try
   try
     Port := 5050;//herhangi bir portno
     ClientType := ctBlocking;//NonBlocking calısmıyor.
     Address := fIp;
     OnConnect := ClntConnect;//baglantı gerceklesince calısacak
     OnDisConnect := Clientsocket1DisConnect;
     onread:= ClientSocket1Read;
     Active := True;
   finally
     Active := False;
   end;
 except
   //baglı olmayan makinalar icin hata verecek
 end;
end;

end.



Cvp: Thread Socket (Yardım) - delphiman - 11-07-2023

(27-04-2020, Saat: 00:43)hkeskin Adlı Kullanıcıdan Alıntı: İyi günler öncelikle 
Socketi Thread içerisinde kullanıyorum fakat thread çalışıyor ClientSocketde öyle bağlanıyor ama hemen arkasından sanırım thread ta kapanıyor Sockette yardımcı olabilecek varmı?
unit unit2;

interface

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

type
 TClientSockThread = class(TThread)
 private
   fIp: string;
   fClientSocket: TClientSocket;
   procedure ClntConnect(Sender: TObject; Socket: TCustomWinSocket);
 protected
   procedure DoTerminate; override;
   procedure Execute; override;
   procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
   procedure ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);

   property Clnt: TClientSocket read fClientSocket write fClientSocket;

 private
   FStream: TFileStream;

 public
   constructor Create(Ip: string);
 end;

 TForm2 = class(TForm)
   Button1: TButton;
   Memo1: TMemo;
   procedure Button1Click(Sender: TObject);
 private

 public
   { Public declarations }
 end;

var
 Form2: TForm2;

implementation

{$R *.DFM}

procedure TClientSockThread.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
var
iLen: Integer;
Bfr: Pointer;
begin
     FStream := TFileStream.Create('C:\Users\hkesk\Desktop\XxXxXx\Win32\Debug\down\somine.mkv', fmCreate or fmShareDenyWrite);
     iLen := Socket.ReceiveLength;
     GetMem(Bfr, iLen);
         try
             Socket.ReceiveBuf(Bfr^, iLen);
             FStream.Write(Bfr^, iLen);
         finally
             FreeMem(Bfr);
         end;
end;

procedure TForm2.Button1Click(Sender: TObject);
var
 i: Integer;
begin
   TClientSockThread.Create('127.0.0.1');
end;

{ TClientSockThread }

procedure TClientSockThread.ClntConnect(Sender: TObject; Socket:
 TCustomWinSocket);
begin
 //formdaki memo yada liste kutusuna baglı olanı ekle
 Form2.Memo1.Lines.Add(Socket.RemoteAddress+' | '+Socket.RemoteHost);
end;

constructor TClientSockThread.Create(Ip: string);
begin
 inherited Create(False);
 fIp := Ip;
 //thread kapanırken kendini sonlandırır.
 //bu ozellik bu gibi durumlarda cok ise yaramakta
FreeOnTerminate := True;
end;

procedure TClientSockThread.DoTerminate;
begin
 //thread sonlanırken clientsocket nesnesi yokedilir.
 fClientSocket.Free;
 inherited DoTerminate;
end;

procedure TClientSockThread.ClientSocket1Disconnect(Sender: TObject; Socket: TCustomWinSocket);
var
 I: Integer;
begin
   Form2.Memo1.Lines.Add('Çıktı..');
end;

procedure TClientSockThread.Execute;
begin
 //socket create edilir.
 fClientSocket := TClientSocket.Create(nil);

 with fClientSocket do
 try
   try
     Port := 5050;//herhangi bir portno
     ClientType := ctBlocking;//NonBlocking calısmıyor.
     Address := fIp;
     OnConnect := ClntConnect;//baglantı gerceklesince calısacak
     OnDisConnect := Clientsocket1DisConnect;
     onread:= ClientSocket1Read;
     Active := True;
   finally
     Active := False;
   end;
 except
   //baglı olmayan makinalar icin hata verecek
 end;
end;

end.

Sanırım sorun, Thread'in kapanması sebebiyle ClientSocket'in de kapanmasıdır. Thread'in sürekli olarak çalışması, ClientSocket bağlantısını koruyacaktır. Thread'in çalışmasını durdurduğunuzda ClientSocket otomatik olarak kapatılacaktır.

Aşağıda örnek bir kod bulunmaktadır. Bu örnekte Thread, ClientSocket bağlantısını sürekli olarak dinleyecek ve bağlantıyı koruyacaktır.

type
  TMyThread = class(TThread)
 private
   FClientSocket: TClientSocket;
 protected
   procedure Execute; override;
 public
   constructor Create(ClientSocket: TClientSocket);
 end;

var
 MyThread: TMyThread;

constructor TMyThread.Create(ClientSocket: TClientSocket);
begin
 FClientSocket := ClientSocket;
 inherited Create(False);
end;

procedure TMyThread.Execute;
var
 ReceivedData: string;
begin
 while not Terminated do
 begin
   try
     ReceivedData := FClientSocket.ReceiveText;
     if ReceivedData <> '' then
     begin
       // Gelen verileri işle
     end;
   except
     // Hata olursa işle
   end;
 end;
end;

// ClientSocket bağlantısını oluşturma işlemi
procedure TForm1.Button1Click(Sender: TObject);
begin
 ClientSocket1.Host := 'localhost';
 ClientSocket1.Port := 1234;
 ClientSocket1.Active := True;

 MyThread := TMyThread.Create(ClientSocket1);
end;


Yukarıdaki kod örneğinde, TMyThread adlı bir Thread sınıfı oluşturduk. Bu sınıf, çalışırken ClientSocket bağlantısını sürekli olarak dinleyecektir. Thread oluşturulduktan sonra ClientSocket bağlantısı kurulur ve Thread çalıştırılır.

Thread'in çalışması durdurulduğunda, ClientSocket otomatik olarak kapatılacaktır. Bunu yapmak için terminate fonksiyonunu kullanmanız yeterlidir.
procedure TForm1.Button2Click(Sender: TObject);
begin
 MyThread.Terminate;
 ClientSocket1.Active := False;
end;


Yukarıdaki kod örneğinde, Button2Click olayında Thread'in terminate fonksiyonu çağrılır ve ClientSocket deaktive edilir. Böylece, Thread sona erdiğinde ClientSocket bağlantısı da sonlandırılır.