Установить или получить опции сокета
- Прототипы
-
#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"!
- Return Value
-
Возвращает ноль при успехе, -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");
}
|
- См. также
-
fcntl()
|