A.17 Filedeskriptor-Überlauf mit select()
Die Funktion select() wird häufig und gerne für Mulitplexing-Socket-I/O verwendet. Den Vorzug dieser Funktion haben Sie bereits kennen gelernt. Der Datentyp fd_set wird verwendet um eine Liste von Sockets zu speichern, welche Sie mit den FD_*-Makros manipulieren können. Ein genauerer Blick auf fd_set zeigt uns eine Struktur mit einem Mitglied – ein statisch alloziiertes Array von Integern. Die Größe des Arrays ist abhängig von FD_SETSIZE. Die Größe von FD_SETSIZE ist selten ein Problem – was schon eher ein Problem werden kann, ist, dass die Makros FD_SET() und FD_CLR() (womit ein Socketdeskriptor in fd_set gesetzt bzw. gelöscht wird) keinerlei Überlaufprüfung des Arrays (Bound Check) fd_set machen.
Solange Sie die maximale Anzahl von File -bzw. Socketdeskriptor so lassen, wie dieser mit FD_SETSIZE angegeben und definiert ist, ist das ganze kein Problem. Bedenken Sie allerdings, dass Sie bspw. in einem Serverprogramm, den Wert durch FD_SETSIZE fest einkompiliert haben. Und eben dass ist ein Problem. Was machen Sie auf einem Rechner, wo eben FD_SETSIZE Deskriptoren nicht mehr ausreichen bzw. noch schlimmer, Sie reduzieren die Ressource (bspw. mit der Funktion setrlimit() oder in der Shell mit ulimit -n 512 oder ulimit -n 64). Wenn Sie den Wert erhöhen, so hat dies in Ihrem Serverprogramm keinerlei Effekt, da dieses fest auf FD_SETSIZE einkompiliert ist. Beim reduzieren der maximalen Anzahl von gleichzeitig geöffneten Deskriptoren haben Sie allerdings einen Deskriptor-Überlauf. In solche einem Fall werden Sie wohl nicht drum herum kommen, einen eigenen Datentyp wie fd_set (dynamisches Array) zu erstellen und auch eigene FD_*-Funktionen, welche als Ersatz für die Makros dienen.
|