Zum Hauptinhalt springen

Das folgende STCP-Codefragment demonstriert ein Problem, das ich beobachtet habe. Es blockiert beim recv-Aufruf, bis Daten zu lesen sind, verarbeitet dann die empfangenen Daten und ruft recv erneut auf, das entweder mit weiteren Daten (oder einem Fehler) zurückkehrt oder blockiert. Wenn ein Fehler aufgetreten ist, gibt recv -1 zurück und der Fehlercode wird in der Variablen errno gespeichert. Sieht der Code für Sie in Ordnung aus?

while (1)
   {
   cBytes = recv (socks1, buffer, BUFFERLEN, 0);
   if (cBytes == -1)
      {
      perror ("Unexpected error at recv");
      exit (errno);
      }
   else
      printf ("number of bytes received : %dn", cBytes);
   }

Der Code geht davon aus, dass die Gegenstelle die Verbindung niemals ordnungsgemäß schließt. Wenn die Gegenstelle die Verbindung ordnungsgemäß schließt, d. h. die Funktion close oder shutdown aufruft, zeigt recv dies der lokalen Anwendung an, indem es null Bytes zurückgibt. Nachfolgende Aufrufe von recv geben weiterhin null Bytes zurück. Das Ergebnis ist, dass sich der Code in einer engen Schleife befindet und nichts tut. Zum Beispiel

Anzahl der empfangenen Bytes : 8
Anzahl der empfangenen Bytes : 57
Anzahl der empfangenen Bytes : 16
Anzahl der empfangenen Bytes : 1
Anzahl der empfangenen Bytes : 1
Anzahl der empfangenen Bytes : 0
Anzahl der empfangenen Bytes : 0
Anzahl der empfangenen Bytes : 0
Anzahl der empfangenen Bytes : 0
Anzahl der empfangenen Bytes : 0
. . . . .

Selbst wenn das Anwendungsprotokoll vorschreibt, dass die Gegenstelle die Verbindung niemals ordnungsgemäß schließt, können Sie nicht garantieren, dass die Verbindung niemals ordnungsgemäß geschlossen wird. Die entfernte Anwendung kann einen Fehler haben oder der entfernte TCP-Stack kann eine ordnungsgemäße Schließung durchführen, wenn der Anwendungsprozess beendet wird. Vielleicht hat auch eine andere Anwendung eine Verbindung hergestellt und sie dann geschlossen, als sie nicht die erwartete Antwort erhielt. Eine Sicherheitsüberprüfung (oder ein böswilliger Benutzer), der einen Port-Scan durchführt oder ein Banner abgreift, kann ebenfalls ein "graceful close" durchführen. Das Fazit ist, dass Sie immer den Fall von Null Bytes behandeln müssen.

while (1)
   {
   cBytes = recv (socks1, buffer, BUFFERLEN, 0);
   if (cBytes <= 0)
      {
      if (cBytes < 0)
         {
         perror ("Unexpected error at recv");
         exit (errno);
         }
      else
         {
         printf ("received closen");
         close (socks1);
         exit (0);
         }
      }
   else
      printf ("number of bytes received : %dn", cBytes);
   }

Anzahl der empfangenen Bytes : 28
Anzahl der empfangenen Bytes : 2
Anzahl der empfangenen Bytes : 58
empfangener Abschluss

 

© 2024 Stratus Technologies.