Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Socket .Net, реализация сервера

307
12 февраля 2012 года
Artem_3A
863 / / 11.04.2008
Доброго времени суток, уважаемые.

Имею ряд вопросов и идей относительно работы с сокетами в .Net на стороне сервера. Работать можно несколькими способами.

1. Синхронно. Ну тут все понятно. Плохой это вариант в большем числе случаев, так как сильно большой оверхед на операциях ввода\вывода.
2. Асинхронно. Тут есть два варианта, это во первых через паттерн IAsyncResult или же можно использовать SocketAsyncEventArg. Вроде все классно, но я так понимаю, что при большом количестве запросов будет забит весь пул потоков...
3. Не блокирующий ввод\вывод. Это подразумевает использование Socket.Select. Ну вроде все тоже не плохо. Однако как то не понятно. Есть ли у вас, уважаемые, примеры? Я так понимаю, что мы вызываем селект, он нам фильтрует соккеты на предмет готовности к операциям ввода\вывода, потом вызываем синхронно получение\отправку и уже как бы блокировки нет. Могут ошибаться, поправьте если что не так.

Теперь сама модель работы.
1. Слушаем соккет, как появилось соединение, то создаем поток и в нем работаем синхронно. Не лучший вариант, большой оверхед на создание потоков и переключение контекста.
2. Работаем асинхронно, все через колбеки. Есть подозрения, что пул потов будет полностью занят обработкой соединений...
3. Асинхронно слушаем сокет и при приеме нового соединения добавляем в очередь на обработку. При этом работают пару-тройку потоков-воркеров, которые извлекают из очереди соединения и синхронно через селект, то есть без блокировок, обрабатывают их.

Собственно какой вариант предпочтительней? Асинхронный или синхронно с селектом? Может есть свои предложения, советы, дополнения, поправки, опыт? В идеале как всегда хочется молниеносной обработки запросов и 10к соединений.
5
12 февраля 2012 года
hardcase
4.5K / / 09.08.2005
Цитата: Artem_3A

1. Синхронно. Ну тут все понятно. Плохой это вариант в большем числе случаев, так как сильно большой оверхед на операциях ввода\вывода.


Вы заблуждаетесь - оверхэда никакого нет, просто вызывающий код будет блокирован до завершения операции ввода/вывода.

Цитата: Artem_3A

2. Асинхронно. Тут есть два варианта, это во первых через паттерн IAsyncResult или же можно использовать SocketAsyncEventArg. Вроде все классно, но я так понимаю, что при большом количестве запросов будет забит весь пул потоков...

Наиболее масштабируемое решение реализуется через IAsyncResult, пулы потоков оно не использует (асинхронность сокетов реализована с помощью портов завершения, completion ports).

Цитата: Artem_3A
3. Не блокирующий ввод\вывод.

Он реализуется через IAsyncResult.

Цитата: Artem_3A
Теперь сама модель работы.
1. Слушаем соккет, как появилось соединение, то создаем поток и в нем работаем синхронно. Не лучший вариант, большой оверхед на создание потоков и переключение контекста.

Откуда у вас оверхед? Потоки можно брать из пула (собственного, либо штатного) :) Это нормальное решение, если у вам необходимо обслуживать десяток-другой соединений.

Цитата: Artem_3A

2. Работаем асинхронно, все через колбеки. Есть подозрения, что пул потов будет полностью занят обработкой соединений...
3. Асинхронно слушаем сокет и при приеме нового соединения добавляем в очередь на обработку. При этом работают пару-тройку потоков-воркеров, которые извлекают из очереди соединения и синхронно через селект, то есть без блокировок, обрабатывают их.

Вы измеряли?

Я сделал бы полностью асинхронную обработку без изготовления собственных пулов и провел измерения.

307
12 февраля 2012 года
Artem_3A
863 / / 11.04.2008
Цитата: hardcase
Вы заблуждаетесь - оверхэда никакого нет, просто вызывающий код будет блокирован до завершения операции ввода/вывода.



Я это и имел в виду, ну то есть тот факт, что поток простаивает в ожидании операции ввода\вывода. Наверное не совсем верно выразился.

Цитата:
Наиболее масштабируемое решение реализуется через IAsyncResult, пулы потоков оно не использует (асинхронность сокетов реализована с помощью портов завершения, completion ports).



Хм, не знал. Но в любом случае я так понимаю, что колбек то уйдет в пул потоков. К тому же в случае использования completion ports, то интересно как оно поведет себя под моно, в линуксах completion ports нет, но есть epoll... Вы случайно не в курсе как там это все реализовано?

Цитата:
Он реализуется через IAsyncResult.



А что можете сказать относительно метода Socket.Select? Есть у Вас опыт его использования?

Цитата:
Откуда у вас оверхед? Потоки можно брать из пула (собственного, либо штатного) :) Это нормальное решение, если у вам необходимо обслуживать десяток-другой соединений.



Затраты на переключение контекста. Если количество одновременных запросов достаточно велико и их обработка занимает время, то получаем большое количество конкурирующих потоков. Если ограничить количество потоков, то получаем модель воркеров, как в апаче реализовано и соответственно нужна очередь соединений к обработке.

Цитата:
Вы измеряли?



Попытался, результат получился странный, асинхронная реализация оказалась хуже чем "по потоку на клиента". Позже попробую повторить эксперимент но уже распределив сервер и клиент по разным машинам, сейчас нет такой возможности.

Цитата:
Я сделал бы полностью асинхронную обработку без изготовления собственных пулов и провел измерения.



Фактических этим сейчас и занимаюсь. Просто результаты первых экспериментов не много сбивают с толку.

307
12 февраля 2012 года
Artem_3A
863 / / 11.04.2008
Еще момент. Почему именно IAsyncResult, а не SocketAsyncEventArgs? Это же ведь одно и то же по сути, только модель чуть отличается или я что то не знаю?
5
12 февраля 2012 года
hardcase
4.5K / / 09.08.2005
Цитата: Artem_3A
Еще момент. Почему именно IAsyncResult, а не SocketAsyncEventArgs? Это же ведь одно и то же по сути, только модель чуть отличается или я что то не знаю?


Хм. Про SocketAsyncEventArgs не знал :) Тесно работал с сокетами еще в .NET 2.0 (его тогда небыло). Похоже что действительно, для высокой нагрузки лучше использовать именно SocketAsyncEventArgs.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог