Опции сокетов
Функции setsockopt и getsockopt o o int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); int setsockopt(int sockfd, int level, int optname, const void *optval socklen_t optlen); sockfd – сокет, опции которого нас интересуют level: n n n o o o SOL_SOCKET IPPROTO_TCP … optname – код опции optval – указатель на значение optlen – размер значения
SO_KEEPALIVE o Через определённый интервал (2 ч) автоматически посылаются пустые TCP пакеты n n Другая сторона присылает ACK. – всё в порядке Другая сторона присылает RST – перезагрузился – соединение закрывается с кодом ECONNRESET Ответ не приходит – посылаются повторные пробы, если ответ не приходит в течении 11 минут 15 сек соединение закрывается с кодом ETIMEDOUT Приходит ICMP ошибка – соединение закрывается с соответствующим кодом
Как узнать о проблемах с соединением Что мы делаем Умер процесс Умер хост Нет связи Передаём данные Получаем FIN, определяемый select’ом на чтение. При продолжении отправки получим RST Соединение закроется по таймауту Соединение закроется после получения ICMP уведомления Получаем данные Получаем FIN, recv возвращает 0 Перестаём получать данные Ничего не делаем, KEEPALIVE установлен Получаем FIN, можно определить select’ом на чтение Через 2 часа посылается проба, соединение закрывается по таймауту Через 2 часа посылается проба, соединение закрывается EHOSTUNREACH Ничего не делаем, KEEPALIVE не установлен Получаем FIN, можно определить select’ом на чтение
SO_LINGER o Определяет что делается с неотправленными данными при закрытии сокета функцией close (closesocket). struct linger { int l_onoff; /* 0=удаляются, не ноль=ждем доставки */ int l_linger; /* время ожидания в секундах */ };
SO_LINGER: l_onoff=0 o Данные могут быть потеряны до обработки сервером
SO_LINGER: l_onoff=1 l_linger>0 o Данные всё ещё могут быть потеряны при сбое на стороне сервера.
SO_LINGER: l_onoff=1 l_linger>0 но мало
Используем shutdown o Используя shutdown и последующий recv мы можем дождаться пока соединение не будет закрыто другой стороной.
SO_LINGER: l_onoff=1 l_linger=0 o При закрытии соединения n n Неотправленные данные теряются Соединение закрывается аварийно – посылается RST сlose() возвращается немедленно Новая копия аналогичного соединения может быть создана быстрее чем 2 MSL, и старые пакеты могут быть обработаны как принадлежащие этому соединению
SO_REUSEADDR o o o Позволяет выполнить bind() на порт, для которого уже существует открытое соединение Позволяет запустить несколько серверов, при условии что один делает bind() с указанием адреса INNADDR_ANY, а другие – с указанием конкретных IP Позволяет выполнить bind() с указанием одного и того же порта и адреса.