Einfacher TCP socket server für single Verbindung

Alle Fragen zur Netzwerkkommunikation

Einfacher TCP socket server für single Verbindung

Beitragvon DL3AD » 12. Mär 2019, 17:58 Einfacher TCP socket server für single Verbindung

Hallo,
ich habe ein Server Gerät (Raspi) das Daten in simplen Strings auf Anfrage liefern soll.
Diese Daten möchte ich auf dem Client PC anfragen und abholen.

Die Communikation soll per TCP erfolgen.
Hier mein Testprogramm

Code: Alles auswählen
 
//Initialisierungen
procedure TForm1.FormShow(Sender: TObject);
begin
  sockS:= TTCPBlockSocket.Create;
  sockC:= TTCPBlockSocket.Create;
  //Server Socket
  socks.Bind('127.0.0.1','10001');
  if sockS.LastError <> 0 then
  begin
    ShowMessage('Server Fehler');
    Form1.Close;
  end
  else
  begin
    sockS.Listen;
  end;
  //Client Socket
  sockC.Connect('127.0.0.1','10001');
  if sockC.LastError = 0 then
  begin
    sockC.ConvertLineEnd:= true;
  end
  else
  begin
    ShowMessage('Keine Verbindung !');
    Form1.Close;
  end;
  Memo1.Clear;
  Memo2.Clear;
end;
 
//Beenden
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  sockC.Free;
  sockS.Free;
end;
 
//Server =======================================================================
//Senden
procedure TForm1.Btn_STxClick(Sender: TObject);
begin
  sockS.SendString(Edit2.Text + Chr($13));
end;
 
//Empfang
procedure TForm1.Btn_SRxClick(Sender: TObject);
begin
  Memo2.Append(sockS.RecvPacket(50));
end;
 
//Client =======================================================================
//Senden
procedure TForm1.Btn_CTxClick(Sender: TObject);
begin
  sockC.SendString(Edit1.Text + Chr($13));
end;
 
//Empfang
procedure TForm1.Btn_CRxClick(Sender: TObject);
begin
  Memo1.Append(sockC.RecvPacket(50));
end;                             
 


Der Client Teil funktioniert schon mal prinzipiell - getestet mit einem anderen TCP-Server.
Was mache ich hier an den Serverpart falsch ?
Die IP stellt er zwar zur verfügung und der Client kann sich auch verbinden - aber es gibt keine Kommunikation.

Gruß Frank
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
DL3AD
 
Beiträge: 391
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.8.0 FPC 3.0.4) und Debian Stretch (L 1.8.0 FPC 3.0.4) | 
CPU-Target: 32Bit/64Bit
Nach oben

Beitragvon Socke » 12. Mär 2019, 18:24 Re: Einfacher TCP socket server für single Verbindung

Da du blockierende Sockets verwendest, musst du Client und Server Socket zwingend auf separate Threads oder Prozesse verteilen.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Socke
Lazarusforum e. V.
 
Beiträge: 2592
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon DL3AD » 12. Mär 2019, 18:39 Re: Einfacher TCP socket server für single Verbindung

... ok dann mache ich zum Test mal zwei Programme draus
DL3AD
 
Beiträge: 391
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.8.0 FPC 3.0.4) und Debian Stretch (L 1.8.0 FPC 3.0.4) | 
CPU-Target: 32Bit/64Bit
Nach oben

Beitragvon DL3AD » 12. Mär 2019, 18:44 Re: Einfacher TCP socket server für single Verbindung

... habe nun Client und Server als einzelne Programme laufen - Kommunikation funktioniert immer noch nicht :(
DL3AD
 
Beiträge: 391
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.8.0 FPC 3.0.4) und Debian Stretch (L 1.8.0 FPC 3.0.4) | 
CPU-Target: 32Bit/64Bit
Nach oben

Beitragvon Warf » 12. Mär 2019, 21:12 Re: Einfacher TCP socket server für single Verbindung

Fehlt da nicht ein accept beim Server?
Der listens die ganze Zeit, kann aber wenn eine Verbindung kommt die nicht annehmen
Warf
 
Beiträge: 1109
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

Beitragvon DL3AD » 13. Mär 2019, 13:54 Re: Einfacher TCP socket server für single Verbindung

... wie und wo baut man das accept ein ?
DL3AD
 
Beiträge: 391
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.8.0 FPC 3.0.4) und Debian Stretch (L 1.8.0 FPC 3.0.4) | 
CPU-Target: 32Bit/64Bit
Nach oben

Beitragvon theo » 13. Mär 2019, 14:58 Re: Einfacher TCP socket server für single Verbindung

Ich hatte vor rund hundert Jahren hier mal eine kleine Demo gebastelt: https://lazarusforum.de/viewtopic.php?p=2626#p2626 und jetzt nochmal unten angehängt.
Vllt. hilft das ein bisschen. Benutzt allerdings für den Server einen sep. Thread.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
theo
 
Beiträge: 8166
Registriert: 11. Sep 2006, 18:01

Beitragvon DL3AD » 13. Mär 2019, 17:18 Re: Einfacher TCP socket server für single Verbindung

Hallo theo,

danke Für die Demo - aber da steige ich nicht durch und mit Threads habe ich noch nix gemacht. :shock:
Schau doch mal bitte in den ersten Post - was muss ich da Ändern damit es geht.
Habe mittlerweile Client und Server als separate Programme - so ist es ja auch später.
Der Client läuft - aber der Server nicht.

Gruß Frank
DL3AD
 
Beiträge: 391
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.8.0 FPC 3.0.4) und Debian Stretch (L 1.8.0 FPC 3.0.4) | 
CPU-Target: 32Bit/64Bit
Nach oben

Beitragvon theo » 14. Mär 2019, 10:02 Re: Einfacher TCP socket server für single Verbindung

Ohne Threads habe ich das nie gemacht. Weiß gar nicht ob das geht.
Funktioniert die Demo denn nicht?
Zu Threads kannst du hier lesen: http://wiki.lazarus.freepascal.org/Mult ... n_Tutorial
theo
 
Beiträge: 8166
Registriert: 11. Sep 2006, 18:01

Beitragvon DL3AD » 14. Mär 2019, 11:37 Re: Einfacher TCP socket server für single Verbindung

Hallo theo,

Danke für deine Hilfe - habe es mal mit LNet versucht - da war ein Beispiel bei - das funktioniert 1A.
Was ich besonders erfreulich bei LNet ist, es stellt verschidene Ereignisse zur Verfügung im Gegensatz zu Synapse.

Gruß Frank
DL3AD
 
Beiträge: 391
Registriert: 13. Sep 2013, 11:07
Wohnort: Rügen
OS, Lazarus, FPC: Win7 (L 1.8.0 FPC 3.0.4) und Debian Stretch (L 1.8.0 FPC 3.0.4) | 
CPU-Target: 32Bit/64Bit
Nach oben

Beitragvon theo » 14. Mär 2019, 13:42 Re: Einfacher TCP socket server für single Verbindung

DL3AD hat geschrieben:Danke für deine Hilfe - habe es mal mit LNet versucht - da war ein Beispiel bei - das funktioniert 1A.
Was ich besonders erfreulich bei LNet ist, es stellt verschidene Ereignisse zur Verfügung im Gegensatz zu Synapse.


OK, LNet Ist da für den Einstieg (Server) vielleicht etwas einfacher.
theo
 
Beiträge: 8166
Registriert: 11. Sep 2006, 18:01

Beitragvon Warf » 14. Mär 2019, 22:43 Re: Einfacher TCP socket server für single Verbindung

DL3AD hat geschrieben:Für nen TCP server externe komponenten


Sorry das ich erst jetzt richtig antworten kann (war damals nur am Handy).

Also ein Server läuft normalerweise so ab:
1. Socket Create
2. An Adresse und Port Binden
3. Listen (Socket für einkommende verbindungen öffnen)
4. Accept -> neues Socket für die Client verbindung
5. Thread für neuen Clienten starten, der kann über das client Socket kommunizieren
6. Gehe zu schritt 4 und nimm ne neue verbindung auf oder warte auf beendete verbindungen

Alternativ kannst du auch eine verbindung akzeptieren, auf dem Haupthread kommunizieren und erst wenn die verbindung mit dem Client beendet wurde den Nächsten anzunehmen (das Betriebsystem sollte eingehende verbindungen buffern). Somit brauchst du keine Threads. Wenn du aber mehr als eine verbindung gleichzeitig brauchst musst du aber wohl auf threads zurückgreifen (oder non blocking sockets verwenden, und selbst schedulen, das wird aber sehr schnell sehr hässlich).

Außerdem, du brauchst keine Externen Komponenten für ne TCP verbindung, weder Synapse noch lNet. FreePascal stellt in der FCL die Unit Sockets für low level Cross Platform Socket handling, und die Unit ssockets mit einer sehr angenehmen OOP klassenstruktur für Sockets. Für einen TCP server kannst du einfach die klasse TINetServer verwenden, geht kinderleicht und ist gut erweiterbar, ich hab mal einen beispiel Server angehängt.

Leider gibts praktisch keine Dokumentation und ich hab auch nur durch blick in den Source Code von TFPHTTPServer gefunden, aber die benutzung ist selten einfach:
Code: Alles auswählen
...
// Server erstellen
  FServer := TINetServer.Create(port);
// Keine max connections
  FServer.MaxConnections:=-1;
// Methode die eingehende Connections verarbeiten
  FServer.OnConnect:=@HandleConnection;
 
  FServer.Bind;
  FServer.Listen;
  FServer.StartAccepting; // blockiert bis der server ausgeschaltet wird mit StopAccepting
 
...
 
procedure TServer.HandleConnection(Sender: TObject; Data: TSocketStream);
begin
  // Starte Thread mit Data als Socket zum lesen (Data.Read) und schreiben (Data.Write)
end
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Warf
 
Beiträge: 1109
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

Beitragvon fliegermichl » 15. Mär 2019, 09:50 Re: Einfacher TCP socket server für single Verbindung

Unter Linux kann man auch fpFork() verwenden. Das erstellt eine exakte Kopie des Prozesses. Dann kann man auf die Multithreading Geschichte verzichten.
fliegermichl
 
Beiträge: 312
Registriert: 9. Jun 2011, 08:42

Beitragvon Warf » 15. Mär 2019, 14:57 Re: Einfacher TCP socket server für single Verbindung

fliegermichl hat geschrieben:Unter Linux kann man auch fpFork() verwenden. Das erstellt eine exakte Kopie des Prozesses. Dann kann man auf die Multithreading Geschichte verzichten.


Nicht nur unter Linux, unter jedem Posix, also auch unter BSD oder MacOS. Oder um es anders zu sagen, unter jedem Betriebsystem außer Windows.

Aber fork, obwohl es solche Sachen echt angenehm macht ist verdammt langsam. Auch wenn Copy on Write implementiert ist muss dennoch über alle Memorypages iteriert werden und diese als kopiert markiert werden, das sind c.a. Virtuelle Speichergröße / 4kb iterationen. Das kann bei lange laufenden Programmen gut und gerne mal ein paar Sekunden dauern (im Gegensatz zu den Milli/Nanosekunden die es kostet einen pthread zu spawnen). Mein Rekord liegt bei 6 Stunden pro Fork call, ich weiß bis heute nicht warum, konnte durch vFork das Problem allerdings umgehen. Mal ganz davon abgesehen das ne ganze menge infos im neuen Prozess nicht benötigt werden, z.B. das Server socket. Man umgeht zwar die ganzen Multithreading Probleme, die kann man aber auch umgehen indem man keine Kommunikation zwischen Threads macht.

Fork kommt aus einer zeit als Prozesse nur 2 memory pages hatten, heutzutage ist es aber eher selten eine gute Idee, vor allem da Threading verdammt einfach geworden ist
Warf
 
Beiträge: 1109
Registriert: 23. Sep 2014, 16:46
Wohnort: Aachen
OS, Lazarus, FPC: Mac OSX 10.11 | Win 10 | FPC 3.0.0 | L trunk | 
CPU-Target: x86_64, i368, ARM
Nach oben

Beitragvon fliegermichl » 15. Mär 2019, 16:27 Re: Einfacher TCP socket server für single Verbindung

Ich hatte mal einen Serverprozess gebaut, der verschiedene Datendateien zur Vefügung stellen soll. Da wurde am Anfang nur ein sog. Masterprozess gestartet der auf Verbindungen gewartet hat.
Wenn ein Client den kontaktiert hat, konnte er die zur Verfügung stehenden Datendateien abfragen und in einer separaten Verbindung eine bestimmte Datendatei auswählen.

Der Master hat dann per fpFork eine Kopie seines Prozesses angelegt. Die Kopie hat dann die entsprechende Datendatei geladen und auf einem separaten Port auf Anfragen gelauscht.
Der anfragende Client hat vom Masterprozess dann die Portnummer der Kopie bekommen.

Nun hat der Client die Kopie auf dem neuen Port konnektiert. Der zweite Datenprozess hat danach alsogleich wieder per fpFork eine Kopie von sich angelegt. So konnte der zweite Prozess auf weitere Anfragen zur selben Datendatei warten. Die dritte Kopie hat dann solange mit dem Clienten Daten ausgetauscht wie sie gebraucht wurde.

Das hat jahrlang im praktischen Einsatz einwandfrei funktioniert. Ein Fehler hatte sich aber doch eingeschlichen. Wenn der Client die Verbindung nicht sauber getrennt hat, blieb ein Zombieprozess übrig und dem System gingen dann irgendwann die Prozesshandles aus.

Aber zeitliche Verzögerungen durch das fork konnte ich nicht feststellen.
fliegermichl
 
Beiträge: 312
Registriert: 9. Jun 2011, 08:42

» Weitere Beiträge siehe nächste Seite »
Nächste

Zurück zu Netzwerk



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste

porpoises-institution
accuracy-worried