AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke indy Server und Client komponente

indy Server und Client komponente

Ein Thema von youuu · begonnen am 6. Feb 2012 · letzter Beitrag vom 8. Feb 2012
Antwort Antwort
youuu

Registriert seit: 2. Sep 2008
Ort: Kleve
822 Beiträge
 
Delphi 2010 Professional
 
#1

indy Server und Client komponente

  Alt 6. Feb 2012, 20:05
Hi,

ich benutze die Indy Komponente um von einem Client an den Server Daten zu senden.

von Client zum Server funktioniert alles wunderbar, aber vom Server zum Client gibt es immer einen Socket Error.
Kann es sein, das die IP des clients nicht korrekt ist, da dieser hinter einen Router steckt?

Wenn ja, wie kann man das Problem lösen?
Steven
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.212 Beiträge
 
Delphi XE7 Professional
 
#2

AW: indy Server und Client komponente

  Alt 6. Feb 2012, 22:15
Guten Abend,

server (öffentliche IP-Adresse) ---- (öffentliche IP-Adresse)-Router-(private IP-Adresse)-Client

Wie versuchst Du denn vom Server den Client zu erreichen?

Wenn Client zum Server funktioniert, dann ist (TCP vorausgesetzt) eine Verbindung zustande gekommen.
Eine TCP Verbindung ist in der Regel nicht unidirektional. D.h. der Server kann über den gleichen Weg/die gleiche Verbindung etwas zum Client schicken.

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
2.664 Beiträge
 
Delphi 2009 Professional
 
#3

AW: indy Server und Client komponente

  Alt 7. Feb 2012, 11:05
aber vom Server zum Client gibt es immer einen Socket Error.
Welcher Socket Error ist es denn genau (es gibt viele)? Und wie sieht der Quelltext aus (von Server zu Client)?
Michael Justin
  Mit Zitat antworten Zitat
youuu

Registriert seit: 2. Sep 2008
Ort: Kleve
822 Beiträge
 
Delphi 2010 Professional
 
#4

AW: indy Server und Client komponente

  Alt 8. Feb 2012, 15:33
Entschuldigung, war leider etwas beschäftigt.

Fehler wenn ich vom Server zurück senden möchte ist "Connection Time out"


So sende ich dann zurück:

Delphi-Quellcode:

procedure TForm1.TCPServerExecute(AContext: TIdContext);
begin
  TCPClient.Host := AContext.Binding.PeerIP;
  TCPClient.Connect;
  if TCPClient.Connected then begin
    TCPClient.IOHandler.WriteLn('bla bla');
    TCPClient.Disconnect;
  end;
end;
Also sobald ich eine Nachricht vom Client erhalte, setze ich als Host seine Ip ein und möchte zurück senden.
Steven
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
2.664 Beiträge
 
Delphi 2009 Professional
 
#5

AW: indy Server und Client komponente

  Alt 8. Feb 2012, 16:21

Delphi-Quellcode:
procedure TForm1.TCPServerExecute(AContext: TIdContext);
begin
  TCPClient.Host := AContext.Binding.PeerIP;
  TCPClient.Connect;
  if TCPClient.Connected then begin
    TCPClient.IOHandler.WriteLn('bla bla');
    TCPClient.Disconnect;
  end;
end;
Also sobald ich eine Nachricht vom Client erhalte, setze ich als Host seine Ip ein und möchte zurück senden.
Ich nehme an, TCPClient ist die Indy Client-Komponente, die sich zuvor mit dem Server verbunden hat?

Die darf der Server darf nicht einfach "wiederverwenden". Eigentlich sollte man, um diesen Fehler auszuschliessen getrennte Projekte anlegen (eines für Clients, und eines für Server).

Der Server hat ja schon seit dem Verbindungsaufbau eine stehende Clientverbindung. Deren Socket (IOHandler) kann vom Server benutzt werden um Daten an den Client zu senden.

Nur muss der Server dazu auch die 'richtige' Connection finden, falls mehrere Clients mit dem Server verbunden sind.

Ich habe aber gerade keinen kompletten Beispielcode zur Hand, eigentlich müßte in den Indy Demos etwas sein...
Michael Justin
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.212 Beiträge
 
Delphi XE7 Professional
 
#6

AW: indy Server und Client komponente

  Alt 8. Feb 2012, 16:29
Hallo,

im Prinzip sollte es so gehen.

Delphi-Quellcode:
procedure TConfigService.onExecute(AContext: TIdContext);
  begin
    AContext.Connection.IOHandler.ReadBytes(key,16); // TCP server liest
    AContext.Connection.IOHandler.Write(buffer.Size); // TCP server schickt etwas zum client
    AContext.Connection.IOHandler.Write(buffer,buffer.size); // wie oben
  end;
Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
2.664 Beiträge
 
Delphi 2009 Professional
 
#7

AW: indy Server und Client komponente

  Alt 8. Feb 2012, 16:46
Delphi-Quellcode:
procedure TConfigService.onExecute(AContext: TIdContext);
  begin
    AContext.Connection.IOHandler.ReadBytes(key,16); // TCP server liest
    AContext.Connection.IOHandler.Write(buffer.Size); // TCP server schickt etwas zum client
    AContext.Connection.IOHandler.Write(buffer,buffer.size); // wie oben
  end;
Genau so ist es (wenn TConfigService ein TIdTCPServer ist)

Wichtiges Detail:

OnExecute wird vom TIdTCPServer in einer Schleife immer wiederholt (bis die Verbindung endet).

Man kann den Code noch etwas CPU freundlicher machen (Quelle). Wichtig sind die Kommentare, die ein anderes Vorgehen beschreiben als im Quelltext darüber.
Michael Justin

Geändert von mjustin ( 8. Feb 2012 um 16:54 Uhr)
  Mit Zitat antworten Zitat
youuu

Registriert seit: 2. Sep 2008
Ort: Kleve
822 Beiträge
 
Delphi 2010 Professional
 
#8

AW: indy Server und Client komponente

  Alt 8. Feb 2012, 16:48
Danke, nun klappt alles
Steven
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
2.664 Beiträge
 
Delphi 2009 Professional
 
#9

AW: indy Server und Client komponente

  Alt 8. Feb 2012, 16:58
Hier die stromsparende Variante, nach http://stackoverflow.com/a/544473/80901 (unter Berücksichtigung der Anmerkungen von Remy Lebeau):

Delphi-Quellcode:
procedure TFormMain.IdTCPServerExecute(AContext: TIdContext);
var
  RxBuf: TIdBytes;
begin
  RxBuf := nil;
  with AContext.Connection.IOHandler do
  begin
    if InputBufferIsEmpty then
    begin
      CheckForDataOnSource(10);
    
      if InputBufferIsEmpty then
      begin
        Exit;
      end;

      InputBuffer.ExtractToBytes(RxBuf);

      // process RxBuf as needed...

    end;
  end;
end;
p.s. in diesem Beispiel sendet der Client einen Request, der dann vom Server verarbeitet wird.

Es kann aber im OnExecute Handler als erstes eine Nachricht an den Client gesendet werden. Zum Beispiel, wenn der Server eine interne Queue von Daten hat, die er nach und nach an den Client senden soll.

In diesem Fall würde der OnExecute Handler anders aufgebaut:

* hole ein Element aus der Queue
* falls kein Element vorhanden war, Exit
* sonst: schreibe die Daten an den Client - AContext.Connection.IOHandler.WriteLn(Daten);
* fertig (es sei denn, eine "synchrone" Quittung des Clients wird benötigt, dann weiter mit CheckForDataOnSource(TimeOut);
Michael Justin
habarisoft.com

Geändert von mjustin ( 9. Feb 2012 um 13:53 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2019 by Daniel R. Wolf