Предыдущая | Оглавление | Следующая |
Установить или получить опции сокета
#include <sys/types.h>
#include <sys/socket.h>
int getsockopt(int s, int level, int optname, void *optval,
socklen_t *optlen);
int setsockopt(int s, int level, int optname, const void *optval,
socklen_t optlen);
Сокеты можно настраивать. На самом деле, они такие настраиваемые, что я не смогу об этом рассказать. Тем более, что доступные опции зависят от системы. Но мы поговорим об основах.
В Linux вся информация о настройках сокетов находится в разделе 7. (Введи "man 7 socket")
s - это данный сокет. level должно быть равно SOL_SOCKET. optname указывает имя нужной опции. Полный список есть в man, но вот самые полезные:
SO_BINDTODEVICE |
Связать сокет с символическим именем устройства типа eth0 вместо того, чтобы использовать bind() и связать его с IP-адресом. Узнать имена устройств можно командой ifconfig (под Unix.) |
SO_REUSEADDR | Позволяет другим сокетам привязываться к этому порту, если только сокет не открыт в режиме ожидания соединений. Это позволяет обойти ошибку "Address already in use" при перезапуске сервера. |
SO_BROADCAST | Позволяет датаграммным UDP-сокетам (SOCK_DGRAM) широковещать. Ничего - НИ-ЧЕ-ГО!!! - не делает потоковому TCP-сокету! Бугага! |
Параметр optval, как правило, указывает на int со значением. Если значение булево, ноль обозначает ложь, а не-ноль обозначает истину. Если опция не требует параметра, можно передать NULL вместо optval.
Параметр optlen заполняется функцией getsockopt(), и скорее всего будет равен sizeof(int). Для setsockopt() можно передать NULL.
Внимание: на некоторых системах (например, Sun и Windows), тип значения может быть char, а не int, и вместо int со значением 1 используется значение '1'. Опять-таки, уточни это в справке командами "man setsockopt" и "man 7 socket"!
Возвращает ноль при успехе, -1 при ошибке, сохраняя ее номер в errno.
int optval; int optlen; char *optval2; // установить опцию SO_REUSEADDR в "истину" (1): optval = 1; setsockopt(s1, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); // привязать сокет к устройству (работает не на всех системах) optval2 = "eth1"; // 4 байт, отсюда 4 нижу: setsockopt(s2, SOL_SOCKET, SO_BINDTODEVICE, optval2, 4); // проверить флаг SO_BROADCAST: getsockopt(s3, SOL_SOCKET, SO_BROADCAST, &optval, &optlen); if (optval != 0) { print("SO_BROADCAST включен для s3!\n"); } |
Предыдущая | Оглавление | Следующая |