![]() |
|
Модераторы: feodorv |
![]()
|
|
| nerdy_weirdie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
Добрый вечер. У меня возникла проблема с серверным приложением. Может, кто сталкивался.
Программа принимает подключения от клиентов (accept();) и в потоке работает с ними, завершая работу shutdown()+closesocket(). Основную часть времени соединения находятся в режиме ожидания - нагрузка на канал небольшая. Соединений обычно около 2к. Проблема в следующем: примерно раз в сутки мне приходится рестартовать программу, потому что она перестает принимать подключения, причем на любой открытый сокет, а не только на тот, что принимает основную часть подключений. Клиент получает ошибку "удаленный хост принудительно разорвал соединение". Другие программы при этом сохраняют способность принимать подключения. Такое ощущение, что есть какие-то лимиты у winsocket. Проверил ветку реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters - там нет параметра TcpNumConnections, видимо, не ограничен. В чем может быть дело? |
|||
|
||||
| SVN74 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 740 Регистрация: 5.5.2008 Где: Комсомольск на Дн епре Репутация: 1 Всего: 18 |
А в потоке по работе с клиентом при ошибке соединения сокет закрывается (closesocket) ?
|
|||
|
||||
| J0ker |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 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 |
|||
|
||||
| nerdy_weirdie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
При завершении сеанса работы с клиентом, сервер всегда заканчивает связь вызовами shutdown()+closesocket(). Этого не достаточно? |
|||
|
||||
| J0ker |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 1 Всего: 14 |
проверьте netstat'ом на наличие большого числа сокетов в состояние FIN_WAIT
так-же я не уверен, как у вас обстоит дело со слушающим сокетом - вы его живым держите или после каждого accept'а ребайндаете? Добавлено через 14 минут и 41 секунду да, и на будущее правильная последовательность закрытия TCP соединения: инициатор - инициатор завершения соединения
(*) - должны применяться таймауты - в случае истечения таймаута выполняется переход к shutdown(SD_RECV) |
|||
|
||||
| nerdy_weirdie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
в цикле только accept() + ::CloseHandle(::CreateThread()).
Вот, наблюдаю за нетстатом - пока что только исключительно "ESTABLISHED". |
|||
|
||||
| J0ker |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 1 Всего: 14 |
вы не должны вызывать CreateThread
если вы работаете с MFC - используйте AfxBeginThread для остального - _beginthread CreateThread можно использовать только в raw windows API в этом возможно как раз и проблема |
|||
|
||||
| nerdy_weirdie |
|
||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
Не, MFC не использую. Спасибо за ответ, но мне кажется что в этом врядли может скрываться причина. Будь то AfxBeginThread или _beginthread, все они вызывают ::CreateThread. Добавлено через 11 минут и 15 секунд
Дело в том что, как показывает статистика, основная причина завершения соединения - разрыв подключения к интернету у клиента. Чем это чревато? Незакрытые сокеты видимо не висят, т.к. потоков в момент коллапса наблюдается не больше обычного. Такие ситуации требуют особой обработки сервером? Возможно, в этом и кроется моя проблема. |
||||||
|
|||||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 6 Всего: 207 |
нет такого состояния Добавлено через 5 минут и 2 секунды как именно разрыв происходит? посмотри, в каком состоянии находятся сокеты на стороне сервера сразу станет понятно -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| Олег2005 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 421 Регистрация: 26.5.2005 Где: Рига Латвия Репутация: 6 Всего: 11 |
Какая ОС?
Проблема описана некорректно. Что значит - принимать подключения? Подключения принимаются только на слушающий сокет - параметр длины очереди устанавливается в listen() А поэтому фраза:"перестает принимать подключения, причем на любой открытый сокет, а не только на тот, что принимает основную часть подключений." - абсолютно непонятна. На любой сокет принимать подключения - нельзя - прием идет только по одному - слушающему. А запросы обслуживаются на акцептированных (присоединенных) сокетах. Так что сформулируйте проблему покорректнее |
|||
|
||||
| nerdy_weirdie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
Олег2005, да, я имел ввиду слушающие сокеты, listen()+<accept() в цикле>.
ОС Windows Server 2003, но всё равно об этом патче TCPIP.SYS почитаю, спасибо. Добавлено через 9 минут и 47 секунд Длина очереди в listen() установлена в SOMAXCONN. |
|||
|
||||
| nerdy_weirdie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
При нештатном уходе клиента из онлайна сервер замечает это по 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 |
|||
|
||||
| Олег2005 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 421 Регистрация: 26.5.2005 Где: Рига Латвия Репутация: 6 Всего: 11 |
И сколько же стоит? Добавлено @ 15:49 Как видно все нормально на присоединенных сокетах закрывается. Тогда где же всетаки нештатная ситуация? Это сообщение отредактировал(а) Олег2005 - 30.11.2008, 15:49 |
|||
|
||||
| J0ker |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 1 Всего: 14 |
только они еще и инициализируют библиотеки в потоках - _beginthread - CRT, а AfxBeginThread - CRT и afx я вам совершенно серьезно советую исправить - вероятность что именно здесь собака и порылась очень высока есть после отсылки пакета с выставленым FIN сокет переходит в состояние FIN_WAIT_1, а после приема ACK без FINа переходит в состояние FIN_WAIT_2 правда я не уверен, что netstat эти состояния отображает - не задавался таким вопросом nerdy_weirdie, совершенно серьезно - обрати внимание на ::CreateThread - при отсутствии инициализации библиотек в потоке могут быть точно такие явления как ты описал Это сообщение отредактировал(а) J0ker - 30.11.2008, 19:28 |
|||
|
||||
| Олег2005 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 421 Регистрация: 26.5.2005 Где: Рига Латвия Репутация: 6 Всего: 11 |
Есть еще вариант - на каждый поток выделяется память - 1 мег в раме.
Как с этим делом? |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 6 Всего: 207 |
верно и где здесь FIN_WAIT? -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| nerdy_weirdie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 179 Регистрация: 16.1.2007 Репутация: нет Всего: нет |
Видимо, таки где-то есть утечка хендлов. Вот, таскменеджером наблюдаю.
Сразу после запуска их было примерно по 5 на поток. Через несколько часов около 10 на поток. И сейчас, часов через 8 стало около 12 на поток. Только ума пока что не приложу, откуда они утекают. Может, кто знает какой попроще способ узнать, откуда лишние хендлы при 2000 работающих потоках )) |
|||
|
||||
| J0ker |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 1 Всего: 14 |
имелось ввиду в каком-либо FIN_WAIT - _1 или _2 ну впрочем тебя я не осуждаю - сие очевидно только ОО программистам Добавлено через 5 минут и 4 секунды вы игнорируете мое предупреждение насчет CreateThread CRT и MFC имеют глобальные объекты, которые должны быть инициализированны на каждый поток отдельно - при отсутствии инициализации последствия непредсказуемы и трудно обнаруживаемы в том числе это может быть и утечка ресурсов |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 6 Всего: 207 |
ага, и потом вот из-за таких ОО программистов и ракеты взрываются, и еще куча всего нехорошего происходит очевидно != формально -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| J0ker |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 1 Всего: 14 |
из-за формалистов происходит столько всяких неприятностей, что одной ракетой больше, одной меньше - никакого рояля не играет |
||||
|
|||||
| MiklVolkov |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 1 Регистрация: 4.7.2009 Репутация: нет Всего: нет |
Уважаемые, если проблему решили, то подскажите как?
Я наступил н теже грабли. Есть набор клиент-серверных приложений собственной разработки. Для связи используются сокеты в виде классов в которых реализовна и клиентская и серверная части. Вся часть ПО ответственная за связь вынесена в отдельную DLL. Сервер запускается, клиенты к нему подключаются, отключаются и т.д. и т.п. Все нормально работало неделями - дольше не получалось тестировать непрерывно - приходилось перезапускать. Клиентов было штук 20. Сейчас клиентов увеличил до 150. Теперь все работает но 2,5 дня. Может и дольше - до недели, но не меньше точно. Потом происходит следующая ситуация. Сервер видит подключения клиентов, новые подключаются, старые отключаются, но данные не пересылаются ни в одну сторону. Была идея - сделать перезапуск класса сервера, отвечающего за связь. Обнаружил интересную штуку - если сделать этот перезапуск искусственно - скажем через 1 сутки - все нормально работает. Но если дождаться когда связь "отвалится" сама - увы, клиенты подключаются, а данные не ходят ни в одну сторону. Перезапускаешь приложение - все опять работает. Понятно, что где-то что-то переполняется, но вот что и где? Да, еще забыл добавить интересное наблюдение - перезапуск класса связи искусственно срабатывает 101 раз. А потом надо один фиг перезагружать всю программу целиком. Памяти сколько выделено и нитей - столько же, сколько и при старте программы. А вот насчет netstat - сказать ничего не могу - я только что про нее узнал Средствами VS никаких утечек чего либо не обнаруживается. |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Сети | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |