Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > Закрыть сокет наверняка


Автор: nerdy_weirdie 30.3.2011, 12:50
Добрый день. Тема уже поднималась, но надежного решения я так и не увидел. 
Есть сервер, обслуживающий клиентов. Работает на основе ТСР. После завершения сеанса некоторый небольшой процент соединений остается висеть вечно в состоянии CLOSE_WAIT после закрытия сокета. Где-то 1 из 1000. В результате система со временем падает.
Закрытие сокета всегда происходит следующим образом
Код

        shutdown(m_sockThis,SD_SEND);
        char buf[100];
        int nReceived = 0;
        do
        {
            nReceived = timed_recv(m_sockThis,buf,100,0,10);
        } while(nReceived>0);
        shutdown(m_sockThis,SD_RECEIVE);
        closesocket(m_sockThis);

timed_recv исключений не выбрасывает, реализована при помощи select, recv.
Как реализовать надежное и универсальное закрытие сокетов чтобы не оставалось CLOSE_WAIT?

Автор: boostcoder 30.3.2011, 13:15
Цитата(nerdy_weirdie @  30.3.2011,  12:50 Найти цитируемый пост)
состоянии CLOSE_WAIT

какая функция возвращает это?

Автор: nerdy_weirdie 30.3.2011, 16:26
Цитата(boostcoder @ 30.3.2011,  13:15)
Цитата(nerdy_weirdie @  30.3.2011,  12:50 Найти цитируемый пост)
состоянии CLOSE_WAIT

какая функция возвращает это?

Это я нетстатом смотрю перечень сокетов в системе.

Кстати да, система Windows Server 2003. Компилировал в VS2005.

Автор: nerdy_weirdie 30.3.2011, 22:25
Добавил
Код

BOOL bDontLinger = TRUE;
setsockopt(m_sockThis,SOL_SOCKET,SO_DONTLINGER,(const char*)&bDontLinger,sizeof(bDontLinger));
не помогает.

Автор: nerdy_weirdie 31.3.2011, 13:11
Ё-маё, неужели никто свой серверный апп никогда до ума не доводил?

Автор: boostcoder 31.3.2011, 13:15
Цитата(nerdy_weirdie @  31.3.2011,  13:11 Найти цитируемый пост)
неужели никто свой серверный апп никогда до ума не доводил?

доводил. но написанный с использованием asio ;)

Добавлено через 2 минуты и 16 секунд
Цитата(nerdy_weirdie @  30.3.2011,  12:50 Найти цитируемый пост)
shutdown(m_sockThis,SD_RECEIVE);

а отправку не пробовали?
так:
Код

shutdown(m_sockThis,SD_BOTH);


Добавлено через 3 минуты и 45 секунд
ааа, отправка запрещена в первой строке smile

Добавлено через 8 минут и 25 секунд
почитайте: http://www.opennet.ru/base/dev/reuses.txt.html
как раз на вашу тему.
ну и отпишитесь, если поможет ;)

Добавлено через 9 минут и 48 секунд
и вообще.. в гугле полно инфы по подобной проблеме: http://www.google.ru/search?sourceid=chrome&ie=UTF-8&q=CLOSE_WAIT
неужели ничего не помогло?

Автор: Олег2005 3.4.2011, 19:51
На полученный от клиента сегмент FIN TCP-модуль сервера отсылает клиенту ACK и переходит в состояние CLOSE_WAIT. 
Сокет клиента, получив этот ACK от сервера, переходит в состояние FIN_WAIT_2, ожидая FIN от сервера. 
Чтобы отослать клиенту FIN, сервер должен со своей стороны вызвать shutdown(sd, SHUT_WR). 
В некоторых руководствах сказано, что close() на серверном сокете автоматически выполняет и shutdown(), но в ходе экспериментов на RED HAT 9 было выяснено, что это не так и следует вызывать shutdown(sd, SHUT_WR) явно, иначе после close() серверный сокет так и останется висеть в CLOSE_WAIT, а клиентский в FIN_WAIT_2 (т.е. будут orphan'ами).
Думаю что и на виндах так надо делать - во всяком случае пробоватьь

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)