Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Delphi: Сети > TCP сервер на большое число клиентов |
Автор: Mikel 10.10.2009, 14:20 |
Господа! Ситуация такая: есть сервер с базой данных, есть несколько тысяч клиентов, которые коннектятся к нему и ждут. Клиенты работают с БД ч/з сервер, при изменении базы данных сервер информирует клиентов об изменениях. Сейчас сервер сделан на TWSocketServer из пакета FPiette (ICS). Есть проблемы: при числе клиентов порядка тысячи перестает принимать соединения. Подскажите, пожалуйста, как лучше реализовать подобный сервер. Нужна ли многопоточность, если клиенты в основном не проявляют сетевой активности, разве что при редактировании и когда принимают изменения. |
Автор: Virtuals 10.10.2009, 14:52 |
Mikel, на какой операционке сервер? есть подозрение что ограничение самих виндов... |
Автор: Mikel 10.10.2009, 15:08 |
Сервер на Windows'e. Пробовал на XP x64 и на серверной 2003 Может стоит переписать на многопоточный сервер на Indy? |
Автор: kami 12.10.2009, 13:28 |
Не стоит. Несколько тысяч потоков - это не очень хорошо для ОС. Вряд ли. Сейчас совершенно спокойно создал 2000 соединений вместе с сопутствующими структурами для приема/передачи данных (в смысле - 2000 исходящих и соответственно 2000 входящих) на основе TClient|TServerSocket (обертки работы с ними где-то здесь уже выкладывал). Вернее, не совсем спокойно - после первой тысячи соединений машинка поднапряглась на создании, но в процессе сетевого обмена со всеми клиентами вела себя более чем адекватно. (Vista Home Premium). Добавлено через 2 минуты и 25 секунд А вот отфутболивать соединения может из-за ограничения на количество полуоткрытых соединений (в TCPView от Sysinternals такие соединения идут под флагом SYN_SENT). Afair, их по умолчанию разрешается не более 100. |
Автор: Mikel 12.10.2009, 13:55 |
В Indy 10 в одном потоке с помощью 'fibers' можно работать с несколькими сокетами, т.е. например открыть 1000 потоков в которых могут работать 2000 клиентских сокетов, по 2 на поток. Вообще тест проводил так- соединяются несколько сотен клиентов, но они у меня находятся в одном потоке, т.е. сначала идет соединение всех сокетов, потом отправка регистрационных данных и т.д. Так вот получается что если пытаться подсоединить, например 300 клиентов разом, то сервер выдает ошибку о перегрузке стека. |
Автор: MetalFan 12.10.2009, 17:01 |
имхо стоит почитать про порты завершения... где-то даже толковая статейка попадалась. искать по: "порты завершение" "IO Completion Port" "IOCP" |
Автор: MetalFan 12.10.2009, 17:04 |
ага... вот и статейка на http://www.gamedev.ru/community/mmorpg/articles/?id=2522 |
Автор: Mikel 13.10.2009, 16:29 |
MetalFan, благодарю, ознакомлюсь ![]() kami, я думаю как раз в этом то и проблема, то что он не выполнив до конца обработчик одного сокета берется за другой и из-за этого и происходит переполнение стека... |
Автор: Mikel 20.10.2009, 10:03 |
Сделал на Indy- вообще не катит ![]() Поставил ProcessMessages в обработчики старого сервера на ICS, теперь 100%ый коннект. Ограничения на соединения кстати есть, но не на сервер- с одного компьютера почти 4000 соединения на сервер можно открыть, потом не соединяется, после чего можно законнектиться еще 4000 сокетов с другого компьютера. В общем 8к соединений держит точно. Но есть еще вопрос, оповещение об изменении происходит в цикле, где в каждый сокете высылается пакет информации об изменении. Так вот когда их много, опять перегружается стек. Может где-то еще впихнуть ProcessMessages? ![]() Кстати еще один вопрос- компьютер под сервер все же двухядерник, а в ICS, как я понимаю, все обрабатывается в одном потоке, нужно ли как-то оптимизировать его под систему с несколькими процессорами? |
Автор: MetalFan 21.10.2009, 18:19 |
ээээ... я может чего не понял. но при чем тут потоки и ProcessMessages???? |
Автор: Mikel 22.10.2009, 07:41 |
Прошу прощения, наверное не совсем корректно выразился, первое предложение относилось к Indy, а остальное- вернулся к старому серверу, на ICS, который работает на асинхронных сокетах. |
Автор: dumb 22.10.2009, 08:42 | ||
а создавать руками тысячами потоки - по-любому плохая, негодная идея. и теперь ошибки старой реализации замаскированы ценой тормозов у клиентов. естественно, надо не во все разом "палить", а рассылать "кучками". и, похоже, что ты не проверяешь коды возвратов(send или его ics-"оберток") и состояние сетевого стека. |