Zum Hauptinhalt springen

In diesem Beitrag möchte ich einen häufigen Codierungsfehler besprechen, der dazu führen kann, dass einem Modul die verfügbare Anzahl von stcp-Geräteklonen für die Erstellung von TCP-Sockets ausgeht oder zumindest ernsthaft erschöpft wird.

Jeder Aufruf der Socket-Funktion führt dazu, dass STCP einen neuen Klon des stcp-Geräts erstellt. Die maximale Anzahl der Klone, die erstellt werden können, wird durch das Feld clone_limit im Eintrag devices.tin gesteuert.

/ =Name stcp.m17
     =Modul_Name m17
     =Gerätetyp Streams
     =Zugriffsliste_name stcp_Zugriff
     =Streams_Treiber stcp
     =klon_limit 5120
     =Bemerkung Bietet TCP-API

Sie können sehen, wie viele Klone derzeit in Gebrauch sind, indem Sie die Gerätestruktur in analyze_system dumpen und sich den Wert clone_count ansehen. Wenn clone_count gleich clone_limit ist, geben Aufrufe der Socket-Funktion einen e$clone_limit_exceeded: "Das Klon-Limit für das Gerät wurde überschritten" zurück.

as: match clone; dump_dvt -name stcp.m17
klonen_limit: 5120
clone_count:       42
geklont_von: -27271
remote_klon_limit: 0

Im Allgemeinen folgt auf den Socket-Aufruf, der das Klon-Gerät erzeugt, entweder ein verbinden Aufruf oder binden und lauschen Aufrufen. An diesem Punkt können Sie einen entsprechenden Eintrag sehen, wenn Sie den "netstat-Befehl" ausführen.

netstat -numerisch -all_sockets
Aktive Verbindungen (einschließlich Server)
Proto Recv-Q Send-Q Lokale Adresse Fremde Adresse (Zustand)
tcp 0 0 172.16.124.217:23 192.168.109.22:50038 BETRIEBEN
tcp 0 0 172.16.124.217:22 172.16.124.24:54987 ESTABLISHED
tcp 0 0 10.20.1.1:37 10.20.1.26:1528 TIME_WAIT
tcp 0 0 10.20.1.1:37 10.20.1.27:1579 ZEIT_WARTEN
tcp 0 0 172.16.124.217:61780 192.168.109.22:23 ESTABLISHED
tcp 0 0 172.16.124.217:22 172.16.124.50:17421 ESTABLISHED
tcp 0 0 172.16.124.217:22 172.16.124.50:17658 ESTABLISHED
tcp 0 0 *:23 *:* LISTEN
tcp 0 0 *:6666 *:* LISTEN
tcp 0 0 *:21 *:* LISTEN
tcp 0 0 *:3000 *:* LISTEN
tcp 0 0 *:7 *:* LISTEN
tcp 0 0 *:9 *:* LISTEN
tcp 0 0 *:13 *:* LISTEN
tcp 0 0 *:19 *:* LISTEN
tcp 0 0 *:37 *:* LISTEN
tcp 0 0 *:901 *:* LISTEN
tcp 0 0 *:1414 *:* LISTEN
tcp 0 0 *:81 *:* LISTEN
tcp 0 0 10.20.1.1:37 10.20.1.9:3633 TIME_WAIT
tcp 0 50 10.10.1.1:52653 10.10.1.200:3001 ESTABLISHED
tcp 0 0 10.10.1.1:52624 10.10.1.200:3001 FIN_WAIT_1
tcp 0 0 10.20.1.1:61704 10.20.1.3:48879 ESTABLISHED
tcp 0 0 *:3001 *:* LISTEN
tcp 0 0 *:3002 *:* LISTEN
tcp 0 0 *:3003 *:* LISTEN
tcp 0 0 *:4000 *:* LISTEN
tcp 0 0 172.16.124.217:4000 172.16.124.78:1024 ESTABLISHED
tcp 0 0 172.16.124.217:4000 172.16.124.227:1025 ESTABLISHED
tcp 0 0 *:4001 *:* LISTEN
tcp 0 0 *:4002 *:* LISTEN
tcp 0 0 *:4003 *:* LISTEN
tcp 0 0 *:4004 *:* LISTEN
tcp 0 0 *:22 *:* LISTEN
tcp 0 0 *:4005 *:* LISTEN
tcp 0 0 *:4006 *:* LISTEN
tcp 0 0 172.16.124.217:4006 172.16.124.203:49231 ESTABLISHED
tcp 0 0 *:4007 *:* LISTEN
tcp 0 0 *:4008 *:* LISTEN
tcp 0 0 *:4009 *:* LISTEN
tcp 0 0 172.16.124.217:4008 172.16.124.203:49262 FESTGESTELLT
tcp 0 0 *:4010 *:* LISTEN
tcp 0 0 *:4011 *:* LISTEN
tcp 0 0 *:4012 *:* LISTEN
tcp 0 0 *:4013 *:* LISTEN
tcp 0 0 *:4014 *:* LISTEN
tcp 0 0 *:4015 *:* LISTEN
tcp 0 0 *:80 *:* LISTEN
tcp 0 0 *:9182 *:* LISTEN
tcp 0 0 *:445 *:* LISTEN
tcp 0 0 *:139 *:* LISTEN
tcp 0 0 10.20.1.1:53495 10.20.1.9:48879 ESTABLISHED
tcp 0 0 10.20.1.1:61703 10.20.1.3:48879 ESTABLISHED
tcp 0 0 10.20.1.1:61707 10.20.1.3:48879 ESTABLISHED
tcp 0 0 10.20.1.1:61705 10.20.1.9:48879 ESTABLISHED
tcp 0 0 10.20.1.1:61709 10.20.1.9:48879 ESTABLISHED
tcp 0 0 10.20.1.1:61710 10.20.1.9:48879 ESTABLISHED
tcp 0 0 172.16.124.217:61789 172.16.124.203:4000 ESTABLISHED
tcp 0 400 172.16.124.217:22 172.16.124.50:17674 ESTABLISHED

Wenn Sie die Anzahl der Zeilen zählen, werden Sie mehr als 42 sehen, da nicht jeder von netstat angezeigte Eintrag einen stcp-Geräteklon verwendet. Zum Beispiel OSL-Verbindungen und die X25_cpc-Verbindungen, die mit dem NIO verwendet werden. Schauen Sie sich socket_count.cm für weitere Details an.

Wenn ein Socket-Aufruf ohne Connect oder Bind erfolgt oder der Bind fehlschlägt, kann es zu dem gegenteiligen Problem kommen, dass der Wert von clone_count größer ist als die Anzahl der von netstat angezeigten Einträge.

as: match clone; dump_dvt -name stcp.m17
klonen_limit: 5120
clone_count:       4131
geklont_vom: -23179
remote_klonen_limit: 0
as:

Ich füge die netstat-Ausgabe nicht noch einmal ein, aber glauben Sie mir, sie hat sich gegenüber dem vorherigen Beispiel nicht verändert.

Diese Situation, ein zusätzlicher (4131 - 42) und offensichtlich nicht berücksichtigter STCP-Geräteklon, wurde durch das folgende Codefragment verursacht. Der Code ruft die Socket-Funktion auf, gefolgt von der Bind-Funktion. Wenn die Bindung fehlschlägt, wird eine Schleife ausgeführt. Viele Anwendungen würden einen Timer hinzufügen, um 1, 60 oder 300 Sekunden zu warten und es dann erneut zu versuchen, was das Unvermeidliche nur hinauszögert, vorausgesetzt natürlich, dass die Bedingung, die den Fehler verursacht, nicht verschwindet.

tryAgain = 1;
while (tryAgain)
  {
  if ((socks0 = socket (AF_INET, SOCK_STREAM, 0)) < 0)
     {
     if (debugFlag)
        perror ("badService: can't create listening socket");
     }
  else {
/* build a sockaddr structure holding the address we will bind to.
   The IP address is INADDR_ANY meaning we will listen on all active
   IP addresses */

     bzero ( (char *) &serv_addr, sizeof (serv_addr));
     serv_addr.sin_family        = AF_INET;
     serv_addr.sin_addr.s_addr   = htonl (INADDR_ANY);
     serv_addr.sin_port          = htons (portNumber);

/* now bind to the address and port */
     if (bind (socks0, (struct sockaddr *) &serv_addr,
                                      sizeof (serv_addr)) < 0)
        {
        if (debugFlag)
           perror ("badService: can't bind address, trying again");
        }
     else
        tryAgain = 0;
     }
   }

Der häufigste Fehler ist, dass ein anderer Prozess bereits an den angeforderten Anschluss gebunden ist. Unabhängig von der Ursache des Fehlers besteht die Lösung darin, den Socket zu schließen, nachdem der Bindungsfehler gemeldet wurde.

tryAgain = 1;
while (tryAgain)
  {
  if ((socks0 = socket (AF_INET, SOCK_STREAM, 0)) < 0)
     {
     if (debugFlag)
        perror ("goodService: can't create listening socket");
     }
  else {
/* build a sockaddr structure holding the address we will bind to.
   The IP address is INADDR_ANY meaning we will listen on all active
   IP addresses */

     bzero ( (char *) &serv_addr, sizeof (serv_addr));
     serv_addr.sin_family        = AF_INET;
     serv_addr.sin_addr.s_addr   = htonl (INADDR_ANY);
     serv_addr.sin_port          = htons (portNumber);

/* now bind to the address and port */
     if (bind (socks0, (struct sockaddr *) &serv_addr,
                                      sizeof (serv_addr)) < 0)
        {
        if (debugFlag)
           perror ("goodService: can't bind address, trying again");
        if (close (socks0) < 0)
           if (debugFlag)
              perror ("goodService: can't close old socket");
        }
     else
        tryAgain = 0;
     }
   }

 

In diesem Beitrag ging es um das Erreichen des Klon-Limits aufgrund eines Kodierungsfehlers, aber was ist, wenn kein Fehler vorliegt, wenn die Anwendungsumgebung wirklich alle Klon-Geräte verwendet? Wenn Sie das Systemlimit von 16.000 nicht erreicht haben, können Sie das Limit anheben. Dazu müssen Sie das Feld clone_limit des stcp-Geräts in der Datei devices.tin aktualisieren und die devices.table neu erstellen. Bei Versionen ab 17.1 können Sie den Befehl update_device_info verwenden, um das Limit für den aktuellen Bootvorgang zu erhöhen und sich darauf verlassen, dass die aktualisierte devices.table den nächsten Bootvorgang übernimmt. Bei Versionen vor 17.1 besteht Ihre einzige Möglichkeit darin, neu zu booten. Sie sollten das Limit auf einen Wert setzen, der Ihren aktuellen Bedürfnissen plus dem erwarteten Wachstum entspricht; Sie sollten das Limit nicht einfach auf 16.000 anheben. Selbst wenn Sie keinen Anwendungsfehler haben, der jetzt Klongeräte verbraucht, gibt es keine Garantie, dass Sie in Zukunft keinen haben werden. Eine Anwendung, die alle verfügbaren Klon-Geräte verbraucht, wird auch einen großen Teil des Streamspeichers beanspruchen, und die Erschöpfung des Streamspeichers wird sich negativ auf bestehende TCP-Verbindungen auswirken.

© 2024 Stratus Technologies.