Модераторы: feodorv

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Лимиты Сокета, Сокет перестает принимать подключения 
:(
    Опции темы
nerdy_weirdie
Дата 10.11.2008, 20:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 179
Регистрация: 16.1.2007

Репутация: нет
Всего: нет



Добрый вечер. У меня возникла проблема с серверным приложением. Может, кто сталкивался.
Программа принимает подключения от клиентов (accept();) и в потоке работает с ними, завершая работу shutdown()+closesocket(). Основную часть времени соединения находятся в режиме ожидания - нагрузка на канал небольшая. Соединений обычно около 2к.
Проблема в следующем: примерно раз в сутки мне приходится рестартовать программу, потому что она перестает принимать подключения, причем на любой открытый сокет, а не только на тот, что принимает основную часть подключений. Клиент получает ошибку "удаленный хост принудительно разорвал соединение". Другие программы при этом сохраняют способность принимать подключения.
Такое ощущение, что есть какие-то лимиты у winsocket.
Проверил ветку реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters - там нет параметра TcpNumConnections, видимо, не ограничен.
В чем может быть дело?
PM MAIL   Вверх
SVN74
Дата 10.11.2008, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 5.5.2008
Где: Комсомольск на Дн епре

Репутация: 1
Всего: 18



А в потоке по работе с клиентом при ошибке соединения сокет закрывается (closesocket) ?
PM MAIL WWW   Вверх
J0ker
Дата 10.11.2008, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 1
Всего: 14



http://forum.vingrad.ru/index.php?showtopi...t&p=1680133
сокеты надо правильно закрывать потомучто

Добавлено через 2 минуты и 25 секунд
в winsock есть лимиты на полуоткрытые сокеты, но это относится к исходящим соединениям

Это сообщение отредактировал(а) J0ker - 10.11.2008, 22:32


--------------------
user posted image
PM MAIL   Вверх
nerdy_weirdie
Дата 12.11.2008, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 179
Регистрация: 16.1.2007

Репутация: нет
Всего: нет



Цитата(J0ker @ 10.11.2008,  22:31)
http://forum.vingrad.ru/index.php?showtopi...t&p=1680133
сокеты надо правильно закрывать потомучто

Добавлено @ 22:33
в winsock есть лимиты на полуоткрытые сокеты, но это относится к исходящим соединениям

При завершении сеанса работы с клиентом, сервер всегда заканчивает связь вызовами  shutdown()+closesocket(). Этого не достаточно?
PM MAIL   Вверх
J0ker
Дата 13.11.2008, 21:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 1
Всего: 14



проверьте netstat'ом на наличие большого числа сокетов в состояние FIN_WAIT
так-же я не уверен, как у вас обстоит дело со слушающим сокетом - вы его живым держите или после каждого accept'а ребайндаете?

Добавлено через 14 минут и 41 секунду
да, и на будущее
правильная последовательность закрытия TCP соединения:
инициатор - инициатор завершения соединения
Код

инициатор                          peer
-----------------------------------------------------------------------
shutdown(SD_SEND)          --->    recv пакет длиной 0
recv оставшихся данных*    <---    send оставшихся данных (опционально)
recv пакета длиной 0*      <---    shutdown(SD_BOTH)
shutdown(SD_RECV)                  closesocket()
closesecket()

(*) - должны применяться таймауты - в случае истечения таймаута выполняется переход к shutdown(SD_RECV) 


--------------------
user posted image
PM MAIL   Вверх
nerdy_weirdie
Дата 13.11.2008, 23:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 179
Регистрация: 16.1.2007

Репутация: нет
Всего: нет



в цикле только accept() + ::CloseHandle(::CreateThread()).
Вот, наблюдаю за нетстатом - пока что только исключительно "ESTABLISHED".
PM MAIL   Вверх
J0ker
Дата 14.11.2008, 00:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 1
Всего: 14



вы не должны вызывать CreateThread
если вы работаете с MFC - используйте AfxBeginThread
для остального - _beginthread
CreateThread можно использовать только в raw windows API
в этом возможно как раз и проблема


--------------------
user posted image
PM MAIL   Вверх
nerdy_weirdie
Дата 30.11.2008, 07:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 179
Регистрация: 16.1.2007

Репутация: нет
Всего: нет



Цитата(J0ker @ 14.11.2008,  00:49)
вы не должны вызывать CreateThread
если вы работаете с MFC - используйте AfxBeginThread
для остального - _beginthread
CreateThread можно использовать только в raw windows API
в этом возможно как раз и проблема

Не, MFC не использую.
Спасибо за ответ, но мне кажется что в этом врядли может скрываться причина. Будь то AfxBeginThread или _beginthread, все они вызывают ::CreateThread.

Добавлено через 11 минут и 15 секунд
Цитата(J0ker @ 13.11.2008,  21:22)
проверьте netstat'ом на наличие большого числа сокетов в состояние FIN_WAIT
так-же я не уверен, как у вас обстоит дело со слушающим сокетом - вы его живым держите или после каждого accept'а ребайндаете?

Добавлено @ 21:37
да, и на будущее
правильная последовательность закрытия TCP соединения:
инициатор - инициатор завершения соединения
Код

инициатор                          peer
-----------------------------------------------------------------------
shutdown(SD_SEND)          --->    recv пакет длиной 0
recv оставшихся данных*    <---    send оставшихся данных (опционально)
recv пакета длиной 0*      <---    shutdown(SD_BOTH)
shutdown(SD_RECV)                  closesocket()
closesecket()

(*) - должны применяться таймауты - в случае истечения таймаута выполняется переход к shutdown(SD_RECV)

Дело в том что, как показывает статистика, основная причина завершения соединения - разрыв подключения к интернету у клиента. Чем это чревато? Незакрытые сокеты видимо не висят, т.к. потоков в момент коллапса наблюдается не больше обычного. Такие ситуации требуют особой обработки сервером? Возможно, в этом и кроется моя проблема. 
PM MAIL   Вверх
MAKCim
Дата 30.11.2008, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Цитата(J0ker @  13.11.2008,  21:22 Найти цитируемый пост)
проверьте netstat'ом на наличие большого числа сокетов в состояние FIN_WAIT

нет такого состояния  smile

Добавлено через 5 минут и 2 секунды
Цитата(nerdy_weirdie @  30.11.2008,  07:40 Найти цитируемый пост)
разрыв подключения к интернету у клиента.

как именно разрыв происходит?

посмотри, в каком состоянии находятся сокеты на стороне сервера
сразу станет понятно


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Олег2005
Дата 30.11.2008, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Цитата(nerdy_weirdie @  10.11.2008,  19:24 Найти цитируемый пост)
TcpNumConnections, видимо, не ограничен.

Какая ОС?
Цитата
Windows XP для повышения безопасности введен новый механизм, ограничивающий число одновременных попыток подключений каждого процесса десятью в секунду (но не ограничивающий вообще число установленных одновременных подключений!), что призвано снизить вредоносный эффект от некоторых типов вирусов. Если же опасность новых вирусных эпидемий вас волнует мало, а главное для вас - скорость, то придется пропатчить системный файл TCPIP.SYS (параметр TcpNumConnections реестра не сработает!).


Цитата(nerdy_weirdie @  10.11.2008,  19:24 Найти цитируемый пост)
Проблема в следующем: примерно раз в сутки мне приходится рестартовать программу, потому что она перестает принимать подключения, причем на любой открытый сокет, а не только на тот, что принимает основную часть подключений. Клиент получает ошибку "удаленный хост принудительно разорвал соединение". Другие программы при этом сохраняют способность принимать подключения.

Проблема описана некорректно.
Что значит - принимать подключения?
Подключения принимаются только на слушающий сокет - параметр длины очереди устанавливается в listen()
А поэтому фраза:"перестает принимать подключения, причем на любой открытый сокет, а не только на тот, что принимает основную часть подключений." - абсолютно непонятна.
На любой сокет принимать подключения - нельзя - прием идет только по одному - слушающему.
А запросы обслуживаются на акцептированных (присоединенных) сокетах.
Так что сформулируйте проблему покорректнее


PM MAIL WWW MSN   Вверх
nerdy_weirdie
Дата 30.11.2008, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 179
Регистрация: 16.1.2007

Репутация: нет
Всего: нет



Олег2005, да, я имел ввиду слушающие сокеты, listen()+<accept() в цикле>.
ОС Windows Server 2003, но всё равно об этом патче TCPIP.SYS почитаю, спасибо.

Добавлено через 9 минут и 47 секунд
Длина очереди в listen() установлена в SOMAXCONN.
PM MAIL   Вверх
nerdy_weirdie
Дата 30.11.2008, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 179
Регистрация: 16.1.2007

Репутация: нет
Всего: нет



Цитата(MAKCim @ 30.11.2008,  11:29)
Цитата(nerdy_weirdie @  30.11.2008,  07:40 Найти цитируемый пост)
разрыв подключения к интернету у клиента.

как именно разрыв происходит?

посмотри, в каком состоянии находятся сокеты на стороне сервера
сразу станет понятно

При нештатном уходе клиента из онлайна сервер замечает это по send() == -1,
::GetLastError() == 10054 An existing connection was forcibly closed by the remote host. 

Обрабатывает он эту ситуацию:
shutdown(s,SD_BOTH);
closesocket(s);
Собственно, сокеты незакрытые, видимо, не висят.

Это сообщение отредактировал(а) nerdy_weirdie - 30.11.2008, 15:41
PM MAIL   Вверх
Олег2005
Дата 30.11.2008, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Цитата(nerdy_weirdie @  30.11.2008,  14:12 Найти цитируемый пост)
SOMAXCONN. 

И сколько же стоит?

Добавлено @ 15:49
Цитата(nerdy_weirdie @  30.11.2008,  14:40 Найти цитируемый пост)
При нештатном уходе клиента из онлайна сервер замечает это по send() == -1,
::GetLastError() == 10054 An existing connection was forcibly closed by the remote host. 

Как видно все нормально на присоединенных сокетах закрывается.
Тогда где же всетаки нештатная ситуация?

Это сообщение отредактировал(а) Олег2005 - 30.11.2008, 15:49
PM MAIL WWW MSN   Вверх
J0ker
Дата 30.11.2008, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 1
Всего: 14



Цитата(nerdy_weirdie @  30.11.2008,  07:40 Найти цитируемый пост)
Спасибо за ответ, но мне кажется что в этом врядли может скрываться причина. Будь то AfxBeginThread или _beginthread, все они вызывают ::CreateThread.

только они еще и инициализируют библиотеки в потоках - _beginthread - CRT, а AfxBeginThread - CRT и afx
я вам совершенно серьезно советую исправить - вероятность что именно здесь собака и порылась очень высока


Цитата(MAKCim @  30.11.2008,  11:29 Найти цитируемый пост)
нет такого состояния

есть
после отсылки пакета с выставленым FIN сокет переходит в состояние FIN_WAIT_1, а после приема ACK без FINа переходит в состояние FIN_WAIT_2
правда я не уверен, что netstat эти состояния отображает - не задавался таким вопросом

nerdy_weirdie, совершенно серьезно - обрати внимание на ::CreateThread - при отсутствии инициализации библиотек в потоке могут быть точно такие явления как ты описал

Это сообщение отредактировал(а) J0ker - 30.11.2008, 19:28


--------------------
user posted image
PM MAIL   Вверх
Олег2005
Дата 30.11.2008, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Есть еще вариант - на каждый поток выделяется память - 1 мег в раме.
Как с этим делом?
PM MAIL WWW MSN   Вверх
MAKCim
Дата 30.11.2008, 22:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Цитата(J0ker @  30.11.2008,  19:27 Найти цитируемый пост)
есть
после отсылки пакета с выставленым FIN сокет переходит в состояние FIN_WAIT_1, а после приема ACK без FINа переходит в состояние FIN_WAIT_2

верно
и где здесь FIN_WAIT?  smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
nerdy_weirdie
Дата 30.11.2008, 23:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 179
Регистрация: 16.1.2007

Репутация: нет
Всего: нет



Видимо, таки где-то есть утечка хендлов. Вот, таскменеджером наблюдаю.
Сразу после запуска их было примерно по 5 на поток.
Через несколько часов около 10 на поток.
И сейчас, часов через 8 стало около 12 на поток. Только ума пока что не приложу, откуда они утекают.
Может, кто знает какой попроще способ узнать, откуда лишние хендлы при 2000 работающих потоках ))
PM MAIL   Вверх
J0ker
Дата 1.12.2008, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 1
Всего: 14



Цитата(MAKCim @ 30.11.2008,  22:27)
Цитата(J0ker @  30.11.2008,  19:27 Найти цитируемый пост)
есть
после отсылки пакета с выставленым FIN сокет переходит в состояние FIN_WAIT_1, а после приема ACK без FINа переходит в состояние FIN_WAIT_2

верно
и где здесь FIN_WAIT?  smile

имелось ввиду в каком-либо FIN_WAIT - _1 или _2
ну впрочем тебя я не осуждаю - сие очевидно только ОО программистам  smile

Добавлено через 5 минут и 4 секунды
Цитата(nerdy_weirdie @  30.11.2008,  23:50 Найти цитируемый пост)
Только ума пока что не приложу, откуда они утекают.

вы игнорируете мое предупреждение насчет CreateThread
CRT и MFC имеют глобальные объекты, которые должны быть инициализированны на каждый поток отдельно - при отсутствии инициализации последствия непредсказуемы и трудно обнаруживаемы
в том числе это может быть и утечка ресурсов



--------------------
user posted image
PM MAIL   Вверх
MAKCim
Дата 1.12.2008, 02:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Цитата(J0ker @  1.12.2008,  01:17 Найти цитируемый пост)
ну впрочем тебя я не осуждаю - сие очевидно только ОО программистам 

ага, и потом вот из-за таких ОО программистов и ракеты взрываются, и еще куча всего нехорошего происходит  smile 
очевидно != формально



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
J0ker
Дата 1.12.2008, 03:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 1
Всего: 14



Цитата(MAKCim @ 1.12.2008,  02:21)
Цитата(J0ker @  1.12.2008,  01:17 Найти цитируемый пост)
ну впрочем тебя я не осуждаю - сие очевидно только ОО программистам 

ага, и потом вот из-за таких ОО программистов и ракеты взрываются, и еще куча всего нехорошего происходит  smile 
очевидно != формально

из-за формалистов происходит столько всяких неприятностей, что одной ракетой больше, одной меньше - никакого рояля не играет  smile 


--------------------
user posted image
PM MAIL   Вверх
MiklVolkov
Дата 4.7.2009, 07:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 4.7.2009

Репутация: нет
Всего: нет



Уважаемые, если проблему решили, то подскажите как?
Я наступил н теже грабли.

Есть набор клиент-серверных приложений собственной разработки. Для связи используются сокеты в виде  классов в которых реализовна и клиентская и серверная части. Вся часть ПО ответственная за связь вынесена в отдельную DLL.

Сервер запускается, клиенты к нему подключаются, отключаются и т.д. и т.п.
Все нормально работало неделями - дольше не получалось тестировать непрерывно - приходилось перезапускать.
Клиентов было штук 20.

Сейчас клиентов увеличил до 150. Теперь все работает но 2,5 дня. Может и дольше - до недели, но не меньше точно.
Потом происходит следующая ситуация. Сервер видит подключения клиентов, новые подключаются, старые отключаются, но данные не пересылаются ни в одну сторону.

Была идея - сделать перезапуск класса сервера, отвечающего за связь. Обнаружил интересную штуку - если сделать этот перезапуск искусственно - скажем через 1 сутки - все нормально работает. Но если дождаться когда связь "отвалится" сама - увы, клиенты подключаются, а данные не ходят ни в одну сторону.

Перезапускаешь приложение - все опять работает.
Понятно, что где-то что-то переполняется, но вот что и где?

Да, еще забыл добавить интересное наблюдение - перезапуск класса связи искусственно срабатывает 101 раз. А потом надо один фиг перезагружать всю программу целиком.

Памяти сколько выделено и нитей - столько же, сколько и при старте программы.
А вот насчет netstat - сказать ничего не могу - я только что про нее узнал
Средствами VS никаких утечек чего либо не обнаруживается.

PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0641 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.