Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi IdTCPClient <> IdTCPServer: Verbindungsproblem (https://www.delphipraxis.net/120796-idtcpclient-idtcpserver-verbindungsproblem.html)

Z4ppy 16. Sep 2008 22:02


IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Das ganze ist jetzt etwas kompliziert, aber ich hoffe, dass ihr das versteht :mrgreen:

Ich entwickle gerade ein Chatprogramm, das ohne Server auskommen soll.
Allerdings hab ich keine Lust, 2 unterschiedliche Programme zu machen, die dann jeder besitzen muss... Also mach ich eins, das einen IdTCPClient und einen IdTCPServer enthält.
Als Chatter geb ich meinem Gegenüber meine IP und der verbindet sich zu mir (mittels IdTCPClient). (Später werd ich das vllt. mit nem Server mit MySQL-Datenbank oder so lösen) Nach dem Aufbau der Verbindung wird der Nick übermittelt. Diesen Nick fängt der Server ab, holt sich die IP der Verbindung, gibt sie meinem IdTCPClient und der versucht, sich zum Gegenüber verbinden.
Nun schlägt das aber fehl. Das Gegenüber stellt zu mir eine Verbindung her, ich krieg die IP, aber die Gegenverbindung geht net.

Wenn ich das ganze mit 127.0.0.1 als IP durchführe, erscheint der Fehler auch - es kann also weder am Router, noch an der Firewall liegen - aber woran dann?

Hier noch paar Quellcodeausschnitte:

Klick auf den Connect-Button:
Delphi-Quellcode:
    IdTCPClient1.Host:=IPEdit.Text;
    try
      IdTCPClient1.Connect();
      IdTCPClient1.WriteLn(Chr(255)+'+'+OwnNick);
    except
      Messages.Lines.Add('['+TimeToStr(Time)+'] Error on connecting with '+IPEdit.Text);
      exit;
    end;
Abfangen der Nachricht Chr(255)+'+'+OwnNick:
Delphi-Quellcode:
{in IdTCPServer.Execute}
  //der variable str wurde bereits die nachricht zugeordnet
  if(str[1]=Chr(255)) then begin
    if(str[2]='+') then begin
      Nick:=StrPart(str,3,Length(str)); //StrPart ist meine eigene Funktion ;)
      IdTCPClient1.Host:=AThread.Connection.Socket.Binding.PeerIP; //IP auslesen
      try
        IdTCPClient1.Connect();
      except
        begin
          Messages.Lines.Add('['+TimeToStr(Time)+'] '+Nick+' connected to you, but I can''t create a connection to him/her. :(');
          exit;
        end;
      end;
      Messages.Lines.Add('['+TimeToStr(Time)+'] '+Nick+' connected to you!');
      IdTCPClient1.WriteLn(Chr(255)+'n'+OwnNick);
    end;
  end;
Die Nachricht Chr(255)+'n'+OwnNick wird wiederum auf der Gegenseite ausgewertet, doch das ist nicht von Bedeutung, da dieser Befehl ja nie ausgeführt wird...

MfG Z4ppy

DataCool 16. Sep 2008 22:37

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Hi,

Dir ist schon klar das Du über eine TIdTcpClient Verbindung auch Daten lesen kannst ?!

Zwar ist bei Deinem Ziel schon richtig TIdTcpClient und TIdTcpServer zu verwenden,
allerdings reicht eine Verbindung :

Client A zu Server B

oder

Client B zu Server A.

Gruß Data

Z4ppy 17. Sep 2008 16:55

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Tatsächlich? Hmm, da muss ich mich mal umgucken...

Trotzdem wird mir deshalb net klar, warum denn diese Verbindung nicht möglich ist ;)

MfG Z4ppy

3_of_8 17. Sep 2008 17:06

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Wird die IP richtig ermittelt? Und was für eine Fehlermeldung kommt denn?

Die Muhkuh 17. Sep 2008 17:08

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Könnte es nicht sein, dass die Gegenverbindung nicht klappt, weil der Port schon belegt ist?

alleinherrscher 17. Sep 2008 17:11

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Was ist denn Messages? Ne Memobox? imho is das idTCPServer.execute ein extra Thread. Sämtliche Prozeduren, die auf dein Formular "malen" musst du daher mit dem Thread synchronisieren.

Die Muhkuh 17. Sep 2008 17:13

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Zitat:

Zitat von alleinherrscher
Was ist denn Messages? Ne Memobox? imho is das idTCPServer.execute ein extra Thread. Sämtliche Prozeduren, die auf dein Formular "malen" musst du daher mit dem Thread synchronisieren.

Musst Du nicht ;)

Z4ppy 17. Sep 2008 17:21

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
@3_of_8: Ich hab mir die IP vom Gegenüber anzeigen lassen, die is korrekt (bei Verbindung zu 127.0.0.1 gibts dann auch 127.0.0.1 aus)

@Die Muhkuh: Tja, Client und Server verwenden natürlich denselben Port - ich empfang also eine Verbindung des Anderen auf Port X und versuch dann mit meinem Clienten, ne Verbindung über Port X zum Andern herzustellen - aber das sollte ja eigentlich keine Kollisionen geben, da die eine Verbindung ausgehend, die andere hereinkommend is...

@alleinherrscher: Messages is n TRichEdit... Da kommen halt dann alle Nachrichten rein ;) Und auch solche Meldungen wie "can't connect to ..." usw.

MfG Z4ppy

inherited 17. Sep 2008 17:54

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Wenn ich das richtig sehe, hast du dann aber 2 Server auf einem PC die auf Port X lauschen wollen, das geht nicht.

Z4ppy 17. Sep 2008 19:45

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Nein, ich habe einen ;)
Ich starte den Chat 1mal und gebe dann 127.0.0.1... Der Server im eigenen Programm erhält dann die Nachricht - ich hab also nur einen ;)
Allerdings gibts da dann ne kollision, da ich den Host vom IdTCPClient ändern will (zumindest theoretisch) und dadurch iwie was schief läuft...
Aber das ändert nix daran, dass es via iNet net geht :(

MfG Z4ppy

DataCool 18. Sep 2008 11:06

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
@Z4ppy:
Die Frage von "inherited" ist berechtigt, die Vorgehensweise die Du beschreibst würde 2 Server vorraussetzen
und wie ich oben schon beschrieben habe ist das "flüssiger als Wasser".
Es reicht von Du eine Verbindung vom Client zum Server aufbaust.
Wenn jetzt der Server was an den Client senden will machst Du das über die schon bestehende Connection,
d.h. der Server MUSS NICHT nochmal irgentwohin verbinden, die Verbindung zum Client steht ja schon.
Im Lan sollte das ganze von allein funktionieren, geht die Verbindungs übers Inet dann liegt der Server zu 99,9% hinter einem Router und in diesem muss per Port-Forwarding Dein Port freigeschaltet werden. Oder Du versucht via UPNP automatisch einen Port im Router zu Öffen,
falls jemand dazu eine Lösung hat lasst Sie mich wissen ;-)

@Muhkuh:
Alleinherrscher hat recht alle Aktionen innerhalb des OnExecute des TIdTcpServer laufen in seperaten Threads,
in Indy9 pro Verbindung ein seperater Thread, in Indy10 etwas eleganter aber immer noch Threads.
Deshalb müssen alle Zugriffe auf die VCL/GUI syncronisiert werden.
Klar geht es auch ohne syncronize, aber nur 90 mal von 100 Versuchen ;-)
Tendenz steigend umso mehr Verbindungen/Clients es werden.

Greetz Data

Z4ppy 18. Sep 2008 18:28

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Jaja, ich weiss jetzt, dass es geht, trotzdem würde ich gern wissen, warum mein Code net geht ;) (Auch wenn ichs wohl so lösen werde, wie du gesagt hast)

MfG Z4ppy

PS.: wäre dir noch dankbar, wenn du mir nen Link wegen String von IdTCPServer => IdTCPClient geben könntest... Ich find immer nur das, was mir allerdings net viel weiterhilft :(

[EDIT] Ich hab noch ein Argument für die Sache mit Client auf beiden Seiten... Wenn ich nämlich auf der einen Seite nur den Server laufen hab, muss ich beim Senden der Nachrichten/Dateien immer überprüfen, ob der User nun auf der Seite des Clients oder auf der des Servers ist. Das wirkt sich vermutlich nicht gerade positiv auf die Perfomance aus... Wenn ich das mit 2 Clients mache, kann ich einfach mit den Funktionen von TIdTCPClient die Strings/Streams verschicken ;)

DataCool 18. Sep 2008 19:47

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Hi,

Dein Code geht nicht weil dieser kompletter Schwachsinn ist.
Ich verstehe die Idee von Deiner Beschreibung her :

- Client A verbindet sich zu Server B
- Server B liesst IP aus und ClientB verbindet sich zu Server A

Bei dem Szenario sind aber 2 Server und 2 Clients notwendig.
Über Sinn und Unsinn dieser Methode will ich mich ned äußern.
Für diese Methode übers Internet müßten beide Clients einen offenen Port in der Firewall haben.

Dein genauer Fehler liegt darin das Du innerhalb des TcpServer im OnExecute,
versucht den client der gerade mit deinem server verbunden ist,
erneut zu verbinden, so wie Du es machst würde er theoretisch versuchen
sich mit dem selben Server zu verbinden mit dem er gerade verbunden war :shock:
Logikfehler Deinerseits.
Das Hauptproblem ist aber das Indy mit "Blocking-Sockets" arbeitet,
ich persönlich finde das sehr gut, aber wenn man das nicht weiß
kann es zu Missverständissen kommen.

Deine Procedure OnExecute des Servers läuft innerhalb eines Threads ab
und tritt solange die Verbindung besteht immer und immer wieder ein.
Jetzt versuchst Du innerhalb dieser Procedure den Client "neu zu verbinden".
Theoretisch sollte/müßte dadurch für die erste Verbindung des Client das OnDisconnect
ausgelöst werden und für die neue Verbindung das OnConnect, allerdings wird bei
Dir wahrscheinlich gar nichts passieren, weil der Rechner im OnExecute "festhängt".
Das Problem kann sich unterm Strich auch anders äußern,
trotzdem kann das so nicht funktionieren.


Zitat:

Ich hab noch ein Argument für die Sache mit Client auf beiden Seiten... Wenn ich nämlich auf der einen Seite nur den Server laufen hab, muss ich beim Senden der Nachrichten/Dateien immer überprüfen, ob der User nun auf der Seite des Clients oder auf der des Servers ist. Das wirkt sich vermutlich nicht gerade positiv auf die Perfomance aus... Wenn ich das mit 2 Clients mache, kann ich einfach mit den Funktionen von TIdTCPClient die Strings/Streams verschicken
^^ Schwachsinn, mit Performance hat das nichts zu tuen. Hab jetzt keinen Bock das auch noch breit zu erläutern, glaub mir einfach

Greetz Data

DataCool 18. Sep 2008 20:05

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Zitat:

PS.: wäre dir noch dankbar, wenn du mir nen Link wegen String von IdTCPServer => IdTCPClient geben könntest... Ich find immer nur das, was mir allerdings net viel weiterhilft Sad
Steht eigentlich alles drin was Du zum Denkansatz brauchst.
Aber damit Du nicht weiter auf dem Schlauch stehst:

Indy9:
Innerhalb des Onexecute des Servers:
Athread.connection.readln / writeln

Willst Du nicht direkt auf eine Nachricht des Clients reagieren und
eigenständig etwas an einen Client schicken:
dann must du dir die connection des Clients raussuchen bei indy10 ist es glaube ich
IdTCPServer1.Contexts ist eine TThreadlist in der alle Context-Objekte drin stehen.
bei Indy9: IdTCPServer1.Threads ^^^

Das sollte jetzt aber als Denkansatz reichen,

Greetz Data

P.S.: Was willst Du eigentlich erreichen einen 1:1 chat oder einen 1:n chat ?

Z4ppy 18. Sep 2008 20:06

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Zitat:

Dein genauer Fehler liegt darin das Du innerhalb des TcpServer im OnExecute,
versucht den client der gerade mit deinem server verbunden ist,
erneut zu verbinden, so wie Du es machst würde er theoretisch versuchen
sich mit dem selben Server zu verbinden mit dem er gerade verbunden war
Logikfehler Deinerseits.
Diesen Teil versteh ich iwie net...
ClientA verbindet sich zu ServerB... Der kriegt eine Nachricht vom ClientA (mitm Nick) und veranlasst ClientB dazu, sich zu ServerA zu verbinden... Wo sollte es da denn ne Kollision geben?!

Zitat:

P.S.: Was willst Du eigentlich erreichen einen 1:1 chat oder einen 1:n chat ?
1:1

MfG Z4ppy

DataCool 18. Sep 2008 20:12

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Zitat:

Diesen Teil versteh ich iwie net...
ClientA verbindet sich zu ServerB... Der kriegt eine Nachricht vom ClientA (mitm Nick) und veranlasst ClientB dazu, sich zu ServerA zu verbinden... Wo sollte es da denn ne Kollision geben?!
Weil es in Dein Bsp. keinen ClientB gibt, sondern Du verbindet Client A neu!

Greetz Data

Z4ppy 18. Sep 2008 20:19

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Nee, eigentlich net, aber ich präzisier ja gern nochma :D

Hier ma n Ablauf (bzw. wies ablaufen sollte :D)
1. Auf beiden PCs wird das Proggie gestartet
2. Aufm PC 1 wird die IP von PC 2 (bzw. dessen Router) eingegeben
3. Der IdTCPClient vom PC 1 verbindet sich zum IdTCPServer vom PC 2 und schickt ihm eine Nachricht mitm Nick
4. Der IdTCPServer vom PC 2 erhält diese Nachricht, übergibt die IP vom PC 1/dessen Router an den IdTCPClient vom PC 2
5. Der IdTCPClient vom PC 2 verbindet sich zum IdTCPServer vom PC 1 und schickt diesem ebenso den Nick
6. Der IdTCPServer vom Pc 1 erhält diese Nachricht, speichert den Nick ab
Danach werden noch einige weitere Sachen ausgetauscht, was aber hier net von Bedeutung ist, da der Fehler ja bei 5. entsteht...

MfG Z4ppy

DataCool 18. Sep 2008 20:32

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Hi,

das es so Laufen soll wie Du beschrieben hast war mir schon klar.

Aber Du hast geschrieben :
Zitat:

Ich entwickle gerade ein Chatprogramm, das ohne Server auskommen soll.
Allerdings hab ich keine Lust, 2 unterschiedliche Programme zu machen, die dann jeder besitzen muss... Also mach ich eins, das einen IdTCPClient und einen IdTCPServer enthält.
Kein Server und keine 2 unterschiedlichen Programme.
Das bedeutet für mich das Du mit einem Programm arbeitest das entweder Client oder Server sein kann.
Somit hast Du TcpClient und TcpServer in einem Programm untergebracht.
Und bei Deinem Source Demo ist es im

Klick auf "Connect Button" : IdTCPClient1.Host:=IPEdit.Text;

Innerhalb des Servers OnExecute verwendest Du :
IdTCPClient1.Host:=AThread.Connection.Socket.Bindi ng.PeerIP; //IP auslesen
IdTCPClient1.Connect();

Wenn Du das Programm jetzt mit Dir selbst testet knallt es wie ich beschrieben habe,
mit 2 unterschiedlichen PC's sollte es sogar gehen, wenn Du im OnConnect den Server des Clients auch auf active = true setzt.

Greetz Data

Z4ppy 18. Sep 2008 20:41

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Es geht ja um die Verbindung zwischen 2 PCs :wall: Dass es mit 127.0.0.1 net geht ist ja (wie ich scho auf Seite 1 geschrieben hab) logisch ;)
Und IdTCPServer.Active wird im TForm1.OnCreate auf True gesetzt ;) Der Server is also bei beiden an...

MfG Z4ppy

Z4ppy 19. Sep 2008 18:52

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
*bump*
(Ich weiss, ist evtl. etwas zu früh zum bumpen, aber ich fahr am Sonntag früh in die Ferien und würd dieses Prob gern vorher lösen ;))

MfG Z4ppy

Z4ppy 30. Sep 2008 21:06

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
So, bin zurück aus den Ferien und hab mich gleich wieder hier dran gesetzt...
Nachdem ich ein System eingebaut hatte, das automatisch einen anderen Port für die Rückverbindung benutzt, hab ichs nochmal getestet - Ergebnis: Von mir aus kann ich keine Verbindung erstellen, wenn sich jemand zu mir verbindet, geht es wiederum... Klickt er also auf Connect, so verbindet er sich zu mir, der Versuch, eine Rückverbindung herzustellen, scheitert jedoch. Klicke ich auf Connect, so wird gar keine Verbindung hergestellt...

Woran kann das nun liegen? Es muss ja was mit meinem PC oder Router zu tun haben. Leider funktioniert es auch net, wenn ich die FW ausschalte, daran liegts also auch net... Im Router ist Stat NAT auf meinen PC eingerichtet - an der Hardware FW kanns also auch net liegen - woran dann? :( :wall:

MfG Z4ppy

inherited 30. Sep 2008 21:19

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Wenn ich das richtig verstanden habe schlägt die Verbindung von Dir zu der Gegenstelle fehl. Hat die Gegenstelle auch den Router, sofern vorhanden, richtig konfiguriert?

Z4ppy 30. Sep 2008 22:04

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Ja, Gegenseite ist (soweit ich weiss) richtig konfiguriert...
Naja, ich wart jetz mal noch 2-3 Tage, dann kommt mein neuer PC... Dann kann ichs via LAN testen ;)

MfG Z4ppy

Z4ppy 2. Okt 2008 11:17

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
OK, habe nun nach weiteren Tests herausgefunden, dass es anscheinend an meinem aktuellen PC liegt. So kann ich z.B. via ICQ keine Dateien verschicken, empfangen aber schon. Ich vermute mal, dass eine defekte tcpip.dll oder sowas der Grund ist. Werde mal versuchen, das zu beheben... Danach sollte auf jeden Fall wieder alles klappen ;)

MfG Z4ppy

jokerfacehro 2. Okt 2008 11:29

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
warum bringste nich einfach server und client in einem proggi unter.
der erste chat partner drückt denn server starten und der zweite verbindet sich.

fertig. und wenn die beiden wieder mal mit einander schreiben wolln und der 2. kumpel dem 1.kumpel die ip gibt, macht der halt nen server auf und der andere verbindet, sodass jeweils nur eine kompo des proggis aktiv ist und du behälst trotzdem die flexibilität, dass jeder mal server sein kann.

Z4ppy 2. Okt 2008 11:58

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Wenn de mir nen Tipp gibst, wie man dann Strings vom Server zum Client schicken kann ;)
Hab bissl rumgesucht aber dazu nur ein Thema hier auf DP gefunden, wo allerdings nur von einer Demo von Indy die Rede ist - die find ich aber nirgends...

MfG Z4ppy

jokerfacehro 2. Okt 2008 12:05

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Socket.writeln hatte hier schon jemand geschrieben xD
genau der gleiche befehl wie beim client

wenn der client verbindet, dessen socket speichern und an den senden

[OOT] ich benutz die indykompos nicht, allein schon weil man beim client nen timer braucht.
und die indy demo funktioniert bei mir nichma, bekomm immer ne schöne zugriffsverletzung.
meine favoriten TClientSocket und TServerSocket ^^ [/OOT]


Zitat:

Zitat von DataCool
Indy9:
Innerhalb des Onexecute des Servers:
Athread.connection.readln / writeln


Z4ppy 2. Okt 2008 12:13

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
Jo, aber innerhalb von OnExecute ;)
Das Problem is ja, dass ich auf Knopfdruck was schicken will ;)
Naja, ich werds mir nachher ma angucken ;)

MfG Z4ppy

jokerfacehro 2. Okt 2008 12:15

Re: IdTCPClient <> IdTCPServer: Verbindungsproblem
 
einfach bei onexecute den socket speichern, denn haste den und kannst denn immer darauf zugreifen

edit: der socket sollte auch direkt in deiner TIdTCPServer kompo sein, da du nur eine verbindung hast solltest die da ganz schnell finden.

bei TServerSocket hab ich en array mit active connections


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:58 Uhr.

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