![]() |
Модераторы: Snowy, Poseidon, MetalFan |
![]() ![]() ![]() |
|
_Rin |
|
||||
![]() Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 12.9.2006 Репутация: нет Всего: нет |
Имеется сервер и клиент на Indy.
На сервере создан поток (CommonThread), который занимается обработкой комманд от клиентов и рассылкой результатов обработки клиентам. Клиент шлет комманды серверу и принимает от него результаты её выполнения. Проводится следующее тестирование: 1) запускается сервер. 2) через прокси к нему поключаются клиенты (около 100 и больше), и начинают слать комманды (клиенты запускаются с одной машиины) 3) подключение происходит нормально, на сервере каждому клиенту IdTCPServer выделяет свой поток, CommonThread занимается обработкой комманд и рассылкой результатов. Тут все путем 4) Но при последующем массовом отключении клиентов - на сервере не уничтожаются потоки, которые выделялись данным клиентам.... В приложение сервера может остаться несколько десятков незавершенных потоков. Как правильно завершать потоки клиентов на сервере ? ![]()
CommandList: TThreadList - список комманд, обрабатывается в CommondThread ConnectionList: TThreadList - список поключенных клиентов, в CommondThread на основании данного списка производится рассылка сообщений клиентам |
||||
|
|||||
Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 53 Всего: 484 |
Тут дело не в прокси.
Потоки сами отвалятся со временем. Время зависит только от винды. Если хочется процесс ускорить, то нужно ввести понятие KeepAlive. Если клиент какое-то время ничего не шлёт, сервер его отрубает. Клиент должен или слать периодически незначащие запросы (KeepAlive), если не хочит, чтоб его отстрелили, либо при отстреле заново отключаться. Для этого каждый тред на сервере должен считать время без запросов. Это обычная ситуация для TCP/IP протокола. |
|||
|
||||
_Rin |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 12.9.2006 Репутация: нет Всего: нет |
Сделала следующую проверку на сервере:
- фиксируется время прихода поледнего сообщения от клиента. - это время периодически сравнивается с текущим временем. - если разница составляет более некоторого значения (пока 30 секунд), то на сервере происходит отключение данного клиента (делаю Disconnect). Вроде все работает как надо... ![]() Но при массовом выключении клиентов иногда проиходит зависание одного-двух клиентов (допустим к серверу подключены 150 клиентов, вырубаем всех - 148 выходят нормально, а 2 продолжают висеть в памяти). На сервере при этом может оставаться как раз 2 незавершенных потока. Если убить зависшие клиенты с помощью Windows Task Manager, то на сервере соответсвующие потоки тоже завершаться, при этом возникает исключение: Socket Error # 10054 Connection reset by peer. Что это значит? P.S. тестировние производится на одном компе (и сервер и 150 клиентов работают на одной машине). |
|||
|
||||
Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 53 Всего: 484 |
Это означает, что была попытка чтения из сокета, а клиент отвалился.
Все операции чтения сокета нужно защищать через try .. except |
|||
|
||||
_Rin |
|
||||||||||
![]() Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 12.9.2006 Репутация: нет Всего: нет |
Провела тестирование через прокси сервер....результаты не утешительные - потоки остаются в памяти, и не завершаются (если клиентов меньше 70 - все нормально, 70 и больше - виснут).
есть список подключений и список принятый от клиентов комманд
В чем может быть дело? Может дело не на стороне сервера, а не стороне клиента? |
||||||||||
|
|||||||||||
Rohoss |
|
|||
![]() Начальник интернета ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1308 Регистрация: 9.10.2006 Где: Matrix Репутация: нет Всего: 18 |
Когда больше ровно 70? В смысле не 69 не 71 а именно 70?
|
|||
|
||||
_Rin |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 12.9.2006 Репутация: нет Всего: нет |
Нет.
Если запускается и подключается к серверу 70 или менее клиентов - то при массовом отключениии - на сервере все их потоки уничтожаются. Если запускается и подключается к серверу более 70 клиентов - то при массовом отключениии - на сервере остаются некоторые потоки. |
|||
|
||||
Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 53 Всего: 484 |
Слишком много взаимных блокировок.
Не нужно работать из потока одного сокета с сокетом другого потока. А уж тем более делать для этого тотальные блокировки. Вот и получается, что у тебя один повисший тред блокирует всех остальных. На сервере должно быть минимум блокировок и синхронизаций. Каждый тред должен работать исключительно со своим сокетом. Если нужно отправить что-то на другой сокет - ставь задачу треду, чей сокет. Тред не должен трогать чужие сокеты. В идеале должен быть один центральный тред, которому сдают принятое и который ставит данные тредам на отправку. Остальные треды друг с другом вообще не должны взаимодействовать - только через этот основной центр. А у тебя постоянные перекрёстные блокировки и юзание чужих сокетов. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Сети" | |
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делится вскрытыми компонентами
Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Сети | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |