Перейти к содержимому

Close wait tcp что это

  • автор:

Close wait tcp что это

Прежде чем мы сможем обсудить многие детали действия TCP протокола, нам необходимо ввести подробную терминологию. Для поддержания TCP соединения необходимо иметь несколько переменных. Мы решили, что эти переменные будут помещены в соответствующую запись — блок управления передачей (Transmission Control Block — TCB). Среди переменных блока TCB имеются номера местного и чужого сокетов, флаги безопасности и приоритета для данного соединения, указатели буферов посылки и получения, указатели текущего сегмента и очереди повторной посылки. Кроме всего этого в TCB имеются несколько переменных, имеющих отношение к номерам очередей отправителя и получателя.

Отправление
SND.UNA посылка неподтверждена
SND.NXT послать следующий сегмент
SND.WND отправить окно
SND.UP отправить срочный указатель
SND.WL1 номер очереди сегмента, использованный для обновления последнего окна
SND.WL2 номер подтверждения в сегменте, используемый для обновления последнего окна
ISS первоначальный номер очереди отправления
Получение
RCV.NXT — получить следующий сегмент
RCV.WND — получить окно
RCV.UP — получить срочный указатель
IRS — первоначальный номер очереди получения

Нижеприведенные диаграммы могут помочь связать некоторые из этих переменных с местом в очереди

  1. старые номера очереди, которые получили подтверждение
  2. номера очереди для данных, не получивших подтверждения
  3. номера очереди, допущенные к новой передаче
  4. следующие номера очереди, чья передача еще не разрешена

Окно отправления — это участок очереди, отмеченный меткой 3 на рисунке 2.

  1. старые номера очереди, которые получили подтверждение
  2. номера очереди, допущенные к очередному этапу получения
  3. следующие номера очереди, еще не получившие разрешения

Окно получения — это участок очереди, отмеченный меткой 2 на рисунке 3.

В обсуждении также часто используются некоторые переменные, берущие свое значение из полей очередного сегмента.

Переменные для очередного сегмента

SEG.SEQ номер очереди для сегмента
SEG.ACK номер подтверждения для сегмента
SEG.LEN длина сегмента
SEG.WND окно для сегмента
SEG.UP срочный указатель для сегмента
SEG.PRC приоритет для сегмента

Соединение во время функционирования проходит через серии промежуточных состояний. Это состояния LISTEN, SYN-SENT, SYN-RECEIVED, ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT, а также фиктивное состояние CLOSED. Состояние CLOSED является фиктивным, поскольку оно представляет состояние, когда не существует блока TCP, а потому и нет соединения. Краткое описание состояний:

LISTEN Ожидание запроса на соединение со стороны чужих портов и программ TCP
SYN-SENT Ожидание парного запроса на установление соединения. С нашей стороны запрос уже сделан.
SYN-RECEIVED Ожидание подтверждения после того, как запрос соединения уже принят и отправлен.
ESTABLISHED Состояние открытого соединения, принимаемые данные можно представить пользователю. Это нормальное состояние соединения в фазе передачи данных.
FIN-WAIT-1 Ожидание запроса от чужой программы TCP, или подтверждения ранее отправленного запроса на закрытие соединения.
FIN-WAIT-2 Ожидание запроса на закрытие соединения со стороны чужой программы TCP.
CLOSE-WAIT Ожидание запроса на закрытие соединения со стороны своего клиента.
CLOSING Ожидание подтверждения со стороны чужой программы TCP запроса о закрытии соединения.
LAST-ACK Ожидание запроса на закрытие соединения, ранее отправленного чужой программе TCP (запрос включал также подтверждение получения чужого запроса на закрытие соединения).
TIME-WAIT Ожидание когда истечет достаточное количество времени и можно быть уверенным, что чужая программа TCP получила подтверждение своего запроса на закрытие соединения.
CLOSED Состояние полного отсутствия соединения.

Соединение TCP переходит с одного состояния на другое в ответ на события. Событие — это запросы клиента (открытие, посылка, получение, закрытие, отказ, получение состояния соединения), приход сегментов, и особенно тех, которые содержат флаги SYN, ACK, RST и FIN, а также истечение выделенного времени.

Диаграмма состояний на рисунке иллюстрирует лишь смену состояний, а также вызвавшие это события, производимые действия, но не адреса, условия ошибок, не действия, не связанные прямо с изменением состояния.

Замечание. Данная диаграмма является лишь сводной, но не должна восприниматься как полная спецификация.

Рис. 4 Диаграмма состояний

Большое кол-во CLOSE_WAIT в Linux

Собственно говоря ситуация следующая. Есть самописный софт обрабатывающий клиентские запросы. Любое завершение сессии работы с клиентов организовано через:
shutdown(sock, SHUT_RDWR);
close(sock);

И со временем на сервере накапливается огромное кол-во соединений со статусом CLOSE_WAIT (до 90 тысяч штук). В чем может быть проблема? shutdown или в каких-то специфических настройках системы? И есть ли возможно организовать автоматической убийство таких висящих соединений (допустим по таймауту)?

  • Вопрос задан более трёх лет назад
  • 18612 просмотров

Комментировать
Решения вопроса 0
Ответы на вопрос 4

Таймаут CLOSE_WAIT в линуксе не регулируется.
Состояние сокета CLOSE_WAIT — это когда от удаленной стороны прилетел fin, а локальный сокет еще удерживается программой, и еще не послал свой fin в ответ.
Ищите в своем софте почему сокет не отпускается.

Ответ написан более трёх лет назад
Комментировать
Нравится 1 Комментировать

Значит у вас утечка. И не все завершения сессий обрабатываются корректно. Ищите с дебаггером где утекают сокеты.

Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать
darkslesh @darkslesh Автор вопроса
Для каждого подключившегося ставлю
Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать
darkslesh @darkslesh Автор вопроса
SO_KEEPALIVE = 1
TCP_KEEPIDLE = 30
TCP_KEEPINTVL = 30
TCP_KEEPCNT = 2
Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

linux

  • Linux
  • +2 ещё

Есть утилита для мониторинга UPS?

  • 2 подписчика
  • 4 часа назад
  • 87 просмотров

CLOSE_WAIT ?

Написал сервак . все класно, но когда начал его юзать на «выносливость», то выяснилось, что при коннекте к нему nc xxx.xxx.xxx.xxx port и последующим ctrl-c на серевере вешается CLASE_WAIT на годы долгие )) в чем дело и как с ним бороться, также можно DoS поймать (((, сервак нитевый, с процессами все ясно, убил и конци в воду )))

anonymous
12.09.02 18:51:42 MSD

Не понял, кого убиваем по ctrl-c? Если сервер, то не должно быть так, net/ipv4/tcp.c:tcp_close() переведет в TCP_LAST_ACK если были в TCP_CLOSE_WAIT. Если убит клиент, то это нормально, и ошибка в сервере. Он должен закрыть socket. Полезно посмотреть на сессию tcpdump’ом, посылает ли сервер FIN+ACK?

idle ★★★★★
( 13.09.02 16:21:57 MSD )

Это не на сервере. Это фишка tcp\ip. Он будет ожидать еще некоторое время пакеты, которые могли еще не дойти серверу посли того как ты его отключил. Это сделано для устойчивости клиентов, и чтоб rst лишний раз не слать, прочитай RFC или книжку по TCP_IP. И еще ты уверен что там не TIME_WAIT?

OxiD ★★★★
( 14.09.02 22:30:01 MSD )

Вот как раз TIME_WAIT для того, чтобы ждать некоторое время и повторять ACK на последний FIN, так как этот ACK может потеряться, и другой конец будет FIN повторять. CLOSE_WAIT наступает, когда приходит первый FIN от инициатора shutdown. Теперь ПРОЦЕСС должен закрыть socket - пока он это не сделает, состояние не изменится. В обоих случаях при получении пакета с новыми данными будет выслан RST.

idle ★★★★★
( 15.09.02 01:19:00 MSD )

Короче, < int val = 1; setsockopt(socket,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val)); >сразу после создания сокета через socket() решит эту проблему (для того оно и придумано).

hvv ★
( 16.09.02 18:39:34 MSD )

Нет, SO_REUSEADDR совсем не для того придумано. Это для борьбы с EADDRINUSE в случае, если делается bind() на локальный порт, а на этом порту уже есть connected socket. Например, в состоянии TIME_WAIT. После bind() флаг никак не меняет поведение socket’а.

idle ★★★★★
( 16.09.02 21:16:06 MSD )

Да, я прогнал — думал мы сервер убиваем, а не nc. Тогда на сервере просто сокет надо закрыть (read вернет -1 или 0 — легко это задетектить).
PS: idle а для чего тогда /proc/sys/net/ipv4/vs/timeout_closewait — что будет делаться по истечение того времени?

hvv ★
( 16.09.02 21:44:57 MSD )

А что, есть такой файл /proc/sys/net/ipv4/vs/timeout_closewait ? Я даже не нашел, кто бы мог этот каталог зарегистерить. Очень интересно, это какое ядро ядро? Насчет детектирования тоже не так просто, возможна туча сценариев, когда read() вернет не ноль. Например. Хост А пишет в socket «bye» и закрывает его. Хост В что-то пишет в socket, write() возвращает успех. Пакет от В доходит до А, тот высылает RST, В его получает, выставляет sock->err = EPIPE. Теперь на В: 1 read() == -EPIPE (sock->err и очищает его), 2 read() == «bye», 3 read() == 0.

idle ★★★★★
( 18.09.02 17:50:13 MSD )

Пардон пардон, не заметил, что hvv написал «-1 или 0».

idle ★★★★★
( 18.09.02 17:52:12 MSD )

Братва, сокеты пишу не в первый раз, и отличить TIME_WAIT от TIME_CLOSE тоже могу, все что нужно оп сети уходит и приходит, гарантировано выполнаяется close(socket_descriptor) без ошибок, RFC почти наизусть знаю, и на вопрос как далеко находится клиент — в соседней дырке в свиче 100М, короче все сигналы я ему послал блокировал и разблокировал PIPE и т.д. Я уже сразу закрывал сокет после accept — боюсь это глюк — или что-то в ядре, хотя на другой тачке с такойже конфигурацией летает без воросов

anonymous
( 18.09.02 18:50:07 MSD )

idle: /proc/sys/net/ipv4/vs/timeout_closewait — есть в linux-2.2

Что за состояния CLOSE_WAIT и TIME_WAIT?

Когда я делаю netstat -a на своем копмьютере Windows, я получаю список портов с одним из четырех состояний:

- LISTENING - CLOSE_WAIT - TIME_WAIT - ESTABLISHED 

Что CLOSE_WAIT и TIME_WAIT значит / указывает?

Из-за того, как работает TCP/IP, соединения не могут быть закрыты сразу. Пакеты могут выйти из строя или быть переданы повторно после того, как соединение было закрыто. CLOSE_WAIT указывает, что удаленная конечная точка (другая сторона соединения) закрыла соединение. TIME_WAIT указывает, что локальная конечная точка (эта сторона) закрыла соединение. Соединение поддерживается таким образом, что любые задержанные пакеты могут быть сопоставлены с соединением и обработаны соответствующим образом. Соединения будут удалены, когда они тайм-аут в течение четырех минут. Видеть http://en.wikipedia.org/wiki/Transmission_Control_Protocol для более подробной информации.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка / 5. Количество оценок:

Оценок пока нет. Поставьте оценку первым.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *