Hallo Poolspieler, habe vor einiger Zeit auch mal sowas gebraucht.
Bei mir funktioniert dies super:
Delphi-Quellcode:
type TMessageReceived = procedure(Sender: TObject; Msg: String) of object;
TClientThread = class(TThread)
protected
FClient: TIdUDPClient; //Client socket
FOnReceive: TMessageReceived; //Wird bei Empfang aufgerufen
FTimeout: Integer; //Verbindung-Timeout
procedure Execute; override;
public
constructor Create(AHost: String; APort: Word; ATimeout: Integer = -1; AOnReceive: TMessageReceived = nil; ASuspended: Boolean = False);
property OnReceive: TMessageReceived read FOnReceive write FOnReceive;
property ClientSocket: TIdUDPClient read FClient;
property Timeout: Integer read FTimeout write FTimeout;
end;
constructor TClientThread.Create(AHost: String; APort: Word; ATimeout: Integer = -1; AOnReceive: TMessageReceived = nil; ASuspended: Boolean = False);
begin
inherited Create(True);
FClient := TIdUDPClient.Create(nil);
FTimeout := ATimeout;
FOnReceive := AOnReceive;
FClient.Host := AHost;
FClient.Port := APort;
if not ASuspended then
Resume;
end;
procedure TClientThread.Execute;
var LRead: String;
LCS: TCriticalSection;
begin
FClient.Active:=true;
FClient.ReceiveTimeout:=FTimeout;
LCS := TCriticalSection.Create;
while not (Terminated) and (FClient.Active) do //Bis Thread or Verbindung beendet
begin
LRead := FClient.ReceiveString;
If Lread='' then sleep(1); // wegen Cpu Last
LCS.Acquire;
if Assigned(FOnReceive) then
FOnReceive(Self, LRead);
LCS.Release;
end;
LCS.Acquire;
if FClient.Active then
FClient.Active:=false;
FClient.Free;
LCS.Release;
LCS.Free;
end;
Diese TClientThread Class erzeugst du im Hauptformular, und hängst beim "createn" die Empfangsprocedure ein.
Delphi-Quellcode:
dein_thread:=TClientThread.Create(
ip,port,0,receive,true);
.....
procedure TForm1.receive(Sender: TObject; Msg:
String);
begin
.....
end;
Dort kannst du deine Daten zuverlässig, abholen.
Besser wäre es wenn du nicht mit Strings arbeitest (so wie ich in diesem Beispiel), sondern mit einem Bytearray.
mfg