Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi ClientSocket bekommt keine Verbindung (https://www.delphipraxis.net/172461-clientsocket-bekommt-keine-verbindung.html)

UliBru 5. Jan 2013 13:51

ClientSocket bekommt keine Verbindung
 
Habe ein für mich unverständliches Problem. Siehe Code-Snippet

Delphi-Quellcode:
procedure TMainForm.Button1Click(Sender: TObject);
begin
  ServerSocket1.Port := 8078;
  ServerSocket1.Open;
  if (ServerSocket1.Port = 8078) and (ServerSocket1.Active) then //Server aktiv ??
  begin
    ClientSocket1.Port := 8078;
    ClientSocket1.Address := '127.0.0.1';
    ClientSocket1.Open;
    if ClientSocket1.Active then // <------------------- hier tut sich nichts
      n := ClientSocket1.Socket.SendText(AnsiString('Test'));
    ClientSocket1.Close;
  end;
end;
Ich will für ein Miniprogramm (eigentlich ohne Fenster) die guten alten TClientSocket und TServerSocket verwenden.
Bekomme aber keine Verbindung. Nun hab ich mal alles auf o.g. Schnipsel reduziert.
Der Server wird geöffnet, der Port zugewiesen.
Das Öffnen des Clients klappt nicht, das ClientSocket1.Active bleibt immer false.

Woran kann das liegen, was muss ich evtl. tun ?

Grüsse,
Uli

sx2008 5. Jan 2013 14:15

AW: ClientSocket bekommt keine Verbindung
 
Also ich würde Server und Client getrennt voneinander entwickeln.
Dabei sollte zuerst der Server funktionieren bevor man sich an den Client macht.
Windows hat standardmässig das Programm telnet.exe an Bord mit dem man den Server testen kann.
(manchmal muss man den Telnet-Client nachinstallieren)
Erst wenn dieser Test erfolgreich ist, lohnt es sich mit dem Client zu beginnen.
Der Aufruf in der Eingabeaufforderung lautet:

Code:
C:\> telnet localhost 8078
Entweder kommt eine Verbindung zustande oder nicht.
Falls nicht gibt es ein Problem im Server.

UliBru 5. Jan 2013 15:28

AW: ClientSocket bekommt keine Verbindung
 
Ja, ich hatte zuerst auch den Server unabhängig vom Client geschrieben.
Und wenn ich beim Sever mit
Delphi-Quellcode:
telnet localhost 8078
teste, bekomme ich auch eine Verbindung inkl. Anzeige des gesendeten Textes im Server. Das klappt also.

Meine eigentliche Anwendung (testweise arg geschrumpft) ist
Delphi-Quellcode:
program ACSendCommand;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils, System.Win.ScktComp;

var
  Client: TClientSocket;

begin
  Client := TClientSocket.Create(nil);
  Client.Host := 'localhost';
  Client.Port := 8078;
  Client.Open;
  if Client.Active then // <-----------------------wird nicht aktiv
    Client.Socket.SendText(AnsiString('Test'));
  Client.Close;
  Client.Free;
end.

Ich hab da nun ebenfalls als Hostadresse localhost vorgegeben. Es klappt genausowenig wie mit 127.0.0.1 oder der richtigen IP.
Also scheint da was falsch zu sein im Gegensatz zu Telnet.
Auch ein Senden ohne Abfrage auf den aktiven Client bringt nichts.

Beim Server wird dieselbe ScktComp verwendet. Delphi ist XE2.

sx2008 5. Jan 2013 17:06

AW: ClientSocket bekommt keine Verbindung
 
Unit ScktComp.pas in Projektverzeichnis kopieren und ins Projekt aufnehmen.
(Ggf. muss uses System.Win.ScktComp -> uses ScktComp geändert werden)
Danach kann man auf
Delphi-Quellcode:
if Client.Active then
einen Breakpoint setzen und per Einzelschritt nachforschen woran es klemmt.

Ausserdem sollte man testen, ob das Problem vielleicht nur bei einer Konsolenanwendung besteht.
Sockets melden Ereignisse über Windows Messages; da es bei Konsolenanwendungen keine Messageloop gibt wäre es denkbar, dass dies ein Problem darstellt.

Aphton 5. Jan 2013 18:38

AW: ClientSocket bekommt keine Verbindung
 
Probiers mal so:
Delphi-Quellcode:
  Client.Open;
  Sleep(1000); // 1 sek
  Application.ProcessMessages;
  if Client.Active then // <-----------------------wird nicht aktiv
Ich glaube, die Komponente ist standardmäßig non-blocking - dh. beim Verbindungsaufbau wird das Programm fortgesetzt. Da liefert dir Active false, da evt. noch nicht erfolgreich verbunden wurde.
Das dauert im Schnitt einige Sekunden...

mjustin 5. Jan 2013 19:35

AW: ClientSocket bekommt keine Verbindung
 
Zitat:

Zitat von sx2008 (Beitrag 1197808)
Sockets melden Ereignisse über Windows Messages; da es bei Konsolenanwendungen keine Messageloop gibt wäre es denkbar, dass dies ein Problem darstellt.

Und wie funktioniert dann telnet.exe? :)

Indy und Synapse TCP Clients funktionieren problemlos in Konsole Anwendungen, nur die alten TClient/TServerSockets (asynchron) und andere asynchrone Komponenten wie ICS benötigen die Windows Message Loop, um Gegensatz zu Indy und Synapse (die dadurch auch leichter auf anderen Betriebssystemen einsetzbar sind).

Oft wird aber hier in diesem Zusammenhang 'Sockets' gesagt, aber damit ist dann nicht die allgmein bekannten TCP/IP Sockets, sondern speziell die alten Delphi TClientSocket / TServerSocket Komponenten gemeint.

sx2008 5. Jan 2013 23:21

AW: ClientSocket bekommt keine Verbindung
 
Zitat:

Zitat von mjustin (Beitrag 1197852)
Zitat:

Zitat von sx2008 (Beitrag 1197808)
Sockets melden Ereignisse über Windows Messages; da es bei Konsolenanwendungen keine Message Loop gibt wäre es denkbar, dass dies ein Problem darstellt.

Und wie funktioniert dann telnet.exe? :)

Windows Sockets können Windows Messages versenden (WSAAsyncSelect), müssen aber nicht.
Und Konsolenanwendungen können ein unsichtbares Window + einen Thread erzeugen um die Messages zu empfangen und abzuarbeiten.
Wie das in telnet.exe läuft, weiss ich nicht aber es ein Aspekt der bei asynchronen Sockets beachtet werden sollte.

Zacherl 6. Jan 2013 04:37

AW: ClientSocket bekommt keine Verbindung
 
Genau das hier trifft zu:
Zitat:

Zitat von Aphton (Beitrag 1197842)
Ich glaube, die Komponente ist standardmäßig non-blocking - dh. beim Verbindungsaufbau wird das Programm fortgesetzt. Da liefert dir Active false, da evt. noch nicht erfolgreich verbunden wurde.
Das dauert im Schnitt einige Sekunden...

Als schnelle Lösung würde ich vorschlagen die Eigenschaft ClientType des Sockets auf ctBlocking zu setzen. Ich sehe bei einer Konsolenanwendung sowieso keinen großen Vorteil in non blocking Sockets.

UliBru 6. Jan 2013 09:48

AW: ClientSocket bekommt keine Verbindung [gelöst]
 
Zitat:

Zitat von Zacherl (Beitrag 1197927)
Als schnelle Lösung würde ich vorschlagen die Eigenschaft ClientType des Sockets auf ctBlocking zu setzen. Ich sehe bei einer Konsolenanwendung sowieso keinen großen Vorteil in non blocking Sockets.

Das muss ich nochmal testen. Klingt logisch.
In der Zwischenzeit hab ich es mit Indy getestet und das klappt. Never touch a running system ...

Delphi-Quellcode:
  IdTCPClient1 := TIdTCPClient.Create(nil);
  try
    IdTCPClient1.Host := '127.0.0.1';
    IdTCPClient1.Port := 8078;
    IdTCPClient1.Connect;
    if IdTCPClient1.Connected then
    begin
      IdTCPClient1.IOHandler.Write(s);
      IdTCPClient1.Disconnect;
    end;
  except
    on E: Exception do ;
  end;
  IdTCPClient1.Free;

mjustin 6. Jan 2013 10:22

AW: ClientSocket bekommt keine Verbindung [gelöst]
 
Zitat:

Zitat von UliBru (Beitrag 1197938)
In der Zwischenzeit hab ich es mit Indy getestet und das klappt.

Delphi-Quellcode:
  IdTCPClient1 := TIdTCPClient.Create(nil);
  try
    IdTCPClient1.Host := '127.0.0.1';
    IdTCPClient1.Port := 8078;
    IdTCPClient1.Connect;
    if IdTCPClient1.Connected then
    begin
      IdTCPClient1.IOHandler.Write(s);
      IdTCPClient1.Disconnect;
    end;
  except
    on E: Exception do ;
  end;
  IdTCPClient1.Free;

Man kann das if IdTCPClient1.Connected then ... weglassen, denn wenn der Verbindungsaufbau mit IdTCPClient1.Connected scheitert, wird eine Exception ausgelöst. Die Zeile mit der Abfrage auf Connected würde also nie erreicht.

Sicherheitshalber würde ich das Free in einem finally Block platzieren.


Delphi-Quellcode:
  IdTCPClient1 := TIdTCPClient.Create(nil);
  try
    IdTCPClient1.Host := '127.0.0.1';
    IdTCPClient1.Port := 8078;
    try
      IdTCPClient1.Connect;
      IdTCPClient1.IOHandler.Write(s);
      IdTCPClient1.Disconnect;
    except
      on E: Exception do
      begin
        Log(E);
        raise;
      end;
    end;
  finally
    IdTCPClient1.Free;  
  end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:32 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz