AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi WinSock: recv()-Puffer wird überschrieben
Thema durchsuchen
Ansicht
Themen-Optionen

WinSock: recv()-Puffer wird überschrieben

Ein Thema von Nogge · begonnen am 27. Aug 2006 · letzter Beitrag vom 1. Sep 2006
Antwort Antwort
Nogge

Registriert seit: 15. Jul 2004
336 Beiträge
 
Delphi 7 Professional
 
#1

WinSock: recv()-Puffer wird überschrieben

  Alt 27. Aug 2006, 12:40
Hallo Community!
Ich habe einen Server mithilfe der WinSock programmiert, der Daten von einem Client zum anderen versendet. Jetzt kommt es allerdings oft vor, dass Client 1 10x in der sec. einen string an den server sendet, die recv()-func allerdings nicht sofort ausgeführt wird. Wenn die recv()-func ausgeführt wird, befinden sich ca. 6.3 (von 10) strings in dem Puffer, obwohl ich mithilfe von recv() jeden string einzeln erhalten möchte.
Hier mal der wichtigste Ausschnitt:
Delphi-Quellcode:
  FTimeVal.tv_sec := 0;
  FTimeVal.tv_usec := 1;

  ClientList := TIntegerList.Create;
  try
    while Server.FServerRunning do
    begin
      FD_ZERO(FDSet);
      FD_SET(Server.AccSock, FDSet);
      for i := 0 to ClientList.Count-1 do
        FD_SET(ClientList[i], FDSet);
      {
        If time-out is a null pointer, select will block indefinitely
        until at least one descriptor meets the specified criteria.
        -------------------------------------------------------------
        -1 = SOCKET_ERROR
        0 = keine Daten vorhanden
      }

      if (select(0, @FDSet, nil, nil, @FTimeVal) > 0) then
      begin
        if not FD_ISSET(Server.AccSock, FDSet) then
        begin
          w := 0;
          count := ClientList.Count;

          while (w < count) do
          begin
            if FD_ISSET(ClientList[w], FDSet) then
            begin
              SetLength(Buffer, MAXLEN);
              BytesRead := recv(ClientList[w], Buffer[1], MAXLEN, 0);
              [...]
Könnt ihr mir sagen, was ich ändern muss, damit ich den Thread jederzeit, wann ich will, mithilfe der Variablen Server.FServerRunning (einfach innerhalb einer Critical Section auf false setzen) beenden kann und doch auf JEDES Datenpaket des Clients reagieren kann?

mfg Nogge
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: WinSock: recv()-Puffer wird überschrieben

  Alt 27. Aug 2006, 12:46
Du mußt dir eine protokoll definieren in dem du die einzelnen gesendeten Datenpackete auf Clientseite wieder zerlegen kannst. Für ein einfaches Protokoll könntest Du z.B. ein im normalen Datenstrom nicht vorkommendes Zeichen verwenden.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Nogge

Registriert seit: 15. Jul 2004
336 Beiträge
 
Delphi 7 Professional
 
#3

Re: WinSock: recv()-Puffer wird überschrieben

  Alt 27. Aug 2006, 12:55
Sorry, Bernhard Geyer, aber ich verstehe absolut nicht, was das mit meinem Problem zu tun haben soll.
Normalerweise sollte BytesRead die Länge eines strings (= ein Datenpaket des CLients) haben. Jedoch erreicht BytesRead ständig MAXLEN, da im Puffer von recv() mehr als ein Datenpaket enthalten ist. Der Client sendet seine Datenpakete so schnell, dass der recv()-Puffer zwischen dem ersten Mal Auslesen und dem nächsten erfolgreichen select() mehr als nur ein Datenpaket vom Client enthält.
Sehr schön wäre es z.B., wenn ich select() als blocking call (@FTimeVal = nil) außerhalb des Threads beenden könnte. Ich weiß leider nicht, ob und wenn, wie das geht.
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: WinSock: recv()-Puffer wird überschrieben

  Alt 27. Aug 2006, 14:43
Also wenn du wirklich einen blockierenden Modus benötigst mußt du:

- Entweder im Client implementieren das erst nach bestätigung vom Server das nächste Packet gesendet wird (Wieder benötigst du die definition eines eigene Protokolls)

- Oder du nimmst komponenten die sowas können wie die Synapse-Komponenten

Soweit ich die mit Delphi gelieferten Socket-Komponeten kenne wirst Du dein gewünschte Verhalten nicht Out-Of-The-Box bekommen.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#5

Re: WinSock: recv()-Puffer wird überschrieben

  Alt 28. Aug 2006, 17:39
@Nogge: Du verstehst uns nicht. Die Sockets übertragen die Daten einfach nur. Da wird nix in so grosse Packete gepackt wie du sie sendest und es gibt nirgendwo auch nur ansatzweise irgendein Teil der Sockets, welche dir garantieren die Daten so geteilt wieder zu empfangen wie du sie losgeschickt hast. Wie kommst du also auf die Idee, dass du genauso aufgeteilte Blöcke wieder empfängst? Ganz im Gegenteil: bei einer schlechten Verbindung kann es sogar sehr gut sein, dass du mehrere recv() haben musst um auch nur einen von deinen Blöcken komplett empfangen zu haben.

Deshalb der Hinweis zum Protokoll, hoffentlich nun verständlicher..
  Mit Zitat antworten Zitat
Nogge

Registriert seit: 15. Jul 2004
336 Beiträge
 
Delphi 7 Professional
 
#6

Re: WinSock: recv()-Puffer wird überschrieben

  Alt 1. Sep 2006, 14:04
Ihr hattet recht. Ich habe die recv()-func nicht richtig verstanden. Selbst wenn diese als blocking-call definiert wird (TimeVal := nil), kann der recv()-Puffer mehr als ein Paket von einem Client empfangen haben ;_;
Nun gut, ich werde jetzt den Vorschlag von Bernhard Geyer umsetzen, bei dem der Client erst nach einer Bestätigung des Servers das nächste Paket senden darf. Dazu muss ich aber noch eins wissen: Jeder Socket, sozusagen jeder Client, hat einen eigenen recv()-Puffer, richtig? Es kann also nicht bei mehreren Sockets ein Paket des ersten Clients mit dem Paket des 2. Clients in einem Puffer enthalten bzw. sogar "vermischt" sein?
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#7

Re: WinSock: recv()-Puffer wird überschrieben

  Alt 1. Sep 2006, 15:04
Nein, nicht bei auf TCP basierenden Dingen.
  Mit Zitat antworten Zitat
Antwort Antwort


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 10:17 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