Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Serversocket ClientRead Problem (https://www.delphipraxis.net/92825-serversocket-clientread-problem.html)

gandime 26. Mai 2007 19:09


Serversocket ClientRead Problem
 
hi,
mein Problem ist folgendes:
da der Tclientsocket erst daten/in meinem fall text schickt wenn er genug daten hat kann es dazu kommen, dass einzelne befehe abgeschnitten sind!
deshalb habe ich mir folgendes ausgedacht:
Delphi-Quellcode:
procedure TForm1.ss_serverClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
  s_receve,s_temp:string;
  b_da:boolean;
  I,i_sockethander: Integer;
begin
  i_sockethander:=socket.SocketHandle;
  for I := 0 to lv_bots.Items.Count - 1 do
  begin
    if (lv_bots.Items.Item[i].SubItems.Strings[8]=inttostr(i_sockethander)) then
    begin
      s_receve:=lv_bots.Items.Item[i].SubItems.Strings[9];
    end;
  end;
  s_receve:=s_receve+Socket.ReceiveText;
  repeat
  begin
    b_da:=false;  //<- break punkt erklärung kommt gleich
    s_temp:='';
    for I := 0 to length(s_receve) -1 do
    begin
      if (s_receve[i]='|') then
      begin
        b_da:=true;
      end;
    end;
    if (b_da=true) then
    begin
      s_temp := copy(s_receve, 1, pos('|', s_receve) - 1);
      s_receve := copy(s_receve, pos('|', s_receve) + 1, length(s_receve));
      for I := 0 to lv_bots.Items.Count - 1 do
      begin
        if (lv_bots.Items.Item[i].SubItems.Strings[8]=inttostr(i_sockethander)) then
        begin
          lv_bots.Items.Item[i].SubItems.Strings[9]:=s_receve;
        end;
      end;
      if (s_temp<>'') then
      begin
        handle(i_sockethander,s_temp);
      end;
    end;
  end;
  until (b_da=false);
end;
nun zu meinem Problem:
die handle procedure wir nicht ausgelöst! Nur wenn ich entweder einen Brak-Punkt ein an die beschiebene stelle setzte oder ich einen button mit
Delphi-Quellcode:
sleep(3000);
machen (der muss aber mindestens 3 sec haben sonst wird die handle Procedure nicht ausgelöst)

wie kann ich mienem Problem abhilfe schaffen?


mfg
gandime

Muetze1 26. Mai 2007 19:28

Re: Serversocket ClientRead Problem
 
Er schickt auch kleinere Packete, aber er macht es abhängig davon ob eine gewisse Grösse erreicht ist oder eine gewisse Zeit vergangen ist.

Dein grundlegendes Problem ist ein Verständnisproblem: Die ClientRead Procedure wird entsprechend auch mehrmals aufgerufen. Du musst also mit jedem ClientRead die Daten akkumulieren und danach schauen, ob du ein komplettes, für dich verarbeitbares, Datenpacket erhalten hast und kannst dann entsprechend Handle() aufrufen. Von daher müsstest du deinen s_receve (receive eigentlich) als Member deklarieren, etc.

gandime 26. Mai 2007 20:51

Re: Serversocket ClientRead Problem
 
ich habe
Zitat:

receive
jetzt als Privat Member deklariert aber es ist immer noch das selbe!

Muetze1 27. Mai 2007 01:34

Re: Serversocket ClientRead Problem
 
Das war auch nur einer der ersten Schritte bis zur Lösung deines Problems. Du musst deine OnClientRead grundsätzlich so umstellen, dass sie mehrfache Aufrufe bis zu einem kompletten Datenpacket abkann und sie auch entsprechend handelt. Grundlegender Ablauf, welcher in deiner ClientRead sein sollte:

1. neue Daten empfangen
2. neue Daten an den Puffer hinten anhängen (s_receive bei dir)
3. vom Anfang des Puffers nachschauen ob ein komplettes Packet enthalten ist (wenn nein, dann Schritt 7)
4. das empfangene Packet aus dem Puffer rausschneiden (also Puffer vorne um diese Länge kürzen)
5. rausgeschnittenes Packet verarbeiten (deine Handle() Methode)
6. zurück zu Punkt 4 (es können mehr als ein komplettes Packet angekommens ein)
7. fertig, Ende der OnClientRead

Wie gesagt, das umdeklarieren war nur der erste Schritt, dazu gehört aber mehr. Du hast den Code bis hierher auch selbst entwickelt, also kannst du die Umstellung auch entsprechend machen.

gandime 27. Mai 2007 19:56

Re: Serversocket ClientRead Problem
 
joo danke jetzt gehts aber warum muss ich es so machen?

Muetze1 28. Mai 2007 01:08

Re: Serversocket ClientRead Problem
 
Du weisst nie wie die Topologie und Infrastruktur aufgebaut ist und von daher weisst du nicht, wie die Packete aufgeteilt werden. Somit muss dein Code ganz grundlegend damit umgehen können.

Du kannst auch einen anderen Weg einschlagen, das Problem ist einfach nur, dass die Sockets asynchron zu deinem Programm Daten versenden und empfangen. Sie geben dir per Callback (event) explizit Bescheid, wenn irgendwas eintritt, auf das du reagieren musst/kannst. Du hast also eine fertige Event-Driven Architektur, warum willst du diese (resourcenschonende) Verarbeitungsweise mit einem Polling (resourcenfressend) ersetzen?

gandime 28. Mai 2007 13:23

Re: Serversocket ClientRead Problem
 
Mich hat es nur interessiert warum ich es auf diese Weise machen muss.
Jetzt weiss ich es also noch mal danke :-)

Caps 26. Jun 2020 13:24

AW: Re: Serversocket ClientRead Problem
 
Sorry, dass ich einen so alten Thread aufwärme, aber ich habe ein Verständnisproblem mit der folgenden Erklärung:

Zitat:

Zitat von Muetze1 (Beitrag 629990)
[…] Grundlegender Ablauf, welcher in deiner ClientRead sein sollte:

1. neue Daten empfangen
2. neue Daten an den Puffer hinten anhängen (s_receive bei dir)
3. vom Anfang des Puffers nachschauen ob ein komplettes Packet enthalten ist (wenn nein, dann Schritt 7)
4. das empfangene Packet aus dem Puffer rausschneiden (also Puffer vorne um diese Länge kürzen)
5. rausgeschnittenes Packet verarbeiten (deine Handle() Methode)
6. zurück zu Punkt 4 (es können mehr als ein komplettes Packet angekommens ein)
7. fertig, Ende der OnClientRead

[…]

Im Schritt 5 wird ein Paket mit Handle() verarbeitet.
Aber was passiert, wenn Handle() sehr lange braucht und in der Zwischenzeit über die TCP-Verbindung neue Daten eintreffen,
wie wird dann "hintenrum" verfahren(?):
- Wird ClientRead parallel (also in einer neuen "Instanz") aufgerufen? (da müssten ClientRead und auch Handle() ja threadsicher sein)
- Oder wartet "die Verbindung" so lange, bis Handle() abgelaufen ist, und ruft dann ClientRead erneut auf?

Falls das eine Rolle spielt, ich verwende einen nicht-blockierenden ServerSocket.

Grüße
Caps


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:40 Uhr.

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