Синхронная и асинхронная работа с сокетами
От: Minimaxus Россия  
Дата: 28.07.06 07:12
Оценка:
Подскажите пожалуйста чем отличается синхронная работа с сокетами от асинхронной!
Хотелось бы знать преимущества и недостатки. Передо мной стояла задача разработки клиент серверной системы (типа ICQ). Работа идет так. Сервер слушает, клиент посылает запрос. Сервер обрабатывает запрос, ои может 1) послать что-то в ответ, 2) ничего не послать, 3) послать другому клиенту. Действия сервера зависят от того, что посылает клиент.
Задачу решил через синхронную работу. Для своего образования решил узнать что изменится, если сделать работу асинхронной. Как это правильнее сделать?
Re: Синхронная и асинхронная работа с сокетами
От: TarasCo  
Дата: 28.07.06 11:37
Оценка:
Здравствуйте, Minimaxus, Вы писали:

M>Подскажите пожалуйста чем отличается синхронная работа с сокетами от асинхронной!

M>Хотелось бы знать преимущества и недостатки. Передо мной стояла задача разработки клиент серверной системы (типа ICQ). Работа идет так. Сервер слушает, клиент посылает запрос. Сервер обрабатывает запрос, ои может 1) послать что-то в ответ, 2) ничего не послать, 3) послать другому клиенту. Действия сервера зависят от того, что посылает клиент.
M>Задачу решил через синхронную работу. Для своего образования решил узнать что изменится, если сделать работу асинхронной. Как это правильнее сделать?

Взгляд со стороны сервера:

Преимущество асихронной модели сервера работы можно "почувстовать" при интенсивной нагрузке на сервер. Допустим, есть однопоточное приложение, работающее по следующему алгоритму:

bind
listen
do {

   accept
   recv
   send
   closesocket

} while( !stop )


Если у сервера мало клиентов, то это вполне надежная схема. Допустим, нагрузка на сервер возросла ( сервис стал популярнее ). Вы готовы поставить многопроцессорную машину, но Ваше приложение не готово — оно однопоточное и не сможет загрузить полностью сервер.

Делаем шаг 2:
bind
listen
do {

   accept
   beginthread

} while( !stop )

thread_routine()
{
   recv
   send
   closesocket
}

Теперь каждый клиент обслуживается в отдельном потоке — задача выполнена, сервер загружается по полной. Допустим нагрузка опять выросла. Это приводит к довольно не приятному последствию — начинают плодиться потоки и производительность серверной системы начинает снижаться, не говоря о том, что возникают задержки в работе ( пока там пара тысяч задач пекреключиться ). И вот нам приходит в голову здравая мысль — если у нас в системе 4 процессора, то хорошо бы сделать четыре потока для обслуживания клиентов. Но клиентов одновременно может быть гораздо больше 4. Значит каждый поток должен быть способен обслуживать несколько клиентов. Какое же основное припятствие для обработки нескольких клиентов одним потоком ( thread_routine )? Да самый основной затык — синхронный вызов recv ( в нашей модели ). Выхода два — использование неблокирующего режима или асинхронного режим. Послений — специфика Windows и на этой платформе данный подход может дать максимальный выигрышь, особенно при применении специального объекта синхронизации — IO completion port.
Да пребудет с тобою сила
Re: Синхронная и асинхронная работа с сокетами
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 30.07.06 09:47
Оценка:
Здравствуйте, Minimaxus, Вы писали:

M>Подскажите пожалуйста чем отличается синхронная работа с сокетами от асинхронной!

M>Хотелось бы знать преимущества и недостатки. Передо мной стояла задача разработки клиент серверной системы (типа ICQ). Работа идет так. Сервер слушает, клиент посылает запрос. Сервер обрабатывает запрос, ои может 1) послать что-то в ответ, 2) ничего не послать, 3) послать другому клиенту. Действия сервера зависят от того, что посылает клиент.
M>Задачу решил через синхронную работу. Для своего образования решил узнать что изменится, если сделать работу асинхронной. Как это правильнее сделать?

Если Вас устраивает синхронная работа — почему бы и нет?
Асинхронная обязательна если нет чётких соединений разделяемых на разные сокеты, всё идёт через один сокет. Это типично для UDP серверов (например, DNS или SIP). Для TCP иногда тоже используется асинхронная организация (на Unix типичный пример — innd), но это нетипично.
The God is real, unless declared integer.
Re[2]: Синхронная и асинхронная работа с сокетами
От: Minimaxus Россия  
Дата: 31.07.06 06:50
Оценка:
N>Асинхронная обязательна если нет чётких соединений разделяемых на разные сокеты, всё идёт через один сокет. Это типично для UDP серверов (например, DNS или SIP). Для TCP иногда тоже используется асинхронная организация (на Unix типичный пример — innd), но это нетипично.
В каких ситуациях один сокет используется? В каких 2 и почему именно так?
Re[2]: Синхронная и асинхронная работа с сокетами
От: Minimaxus Россия  
Дата: 31.07.06 07:00
Оценка:
Спасибо за ответы!
TC>Какое же основное припятствие для обработки нескольких клиентов одним потоком ( thread_routine )? Да самый основной затык — синхронный вызов recv ( в нашей модели ).

А тут подробнее можно в чем именно затык?

TC>Выхода два — использование неблокирующего режима или асинхронного режим. Послений — специфика Windows и на этой платформе данный подход может дать максимальный выигрышь, особенно при применении специального объекта синхронизации — IO completion port.


В асинхронном режиме весь пакет сразу приходит? Или может прийти от одного кусок сообщения, потом от другого клиента, потом снова от первого... Не могу понять большой разницы и преимущества.
Re[3]: Синхронная и асинхронная работа с сокетами
От: TarasCo  
Дата: 31.07.06 07:33
Оценка: 2 (1)
Здравствуйте, Minimaxus, Вы писали:

M>Спасибо за ответы!

TC>>Какое же основное припятствие для обработки нескольких клиентов одним потоком ( thread_routine )? Да самый основной затык — синхронный вызов recv ( в нашей модели ).

M>А тут подробнее можно в чем именно затык?


Ну допустим мы хотим обслуживать два клиента одним потоком. В синхронном режиме это будет выглядеть как то так:


recv( s1, ... );
handle_recv( s1, ... ); //обработка запроса от клиента 1
recv( s2, ... );
handle_recv( s1, ... ); //обработка запроса от клиента 2


Вся беда в том, что запрос от клиента 1 придет допустим спустя 2 секунды, а запрос от клиента 2 уже пришел. Тем не менее, мы будем ждать запрос от клиента 1. При этом: простаивает поток ( а это приводит к недогрузке одного процессора сервера ), задерживается обслуживание второго клиента.

M>В асинхронном режиме весь пакет сразу приходит? Или может прийти от одного кусок сообщения, потом от другого клиента, потом снова от первого.


Естественно, данные могут приходить кусками. Но Вы будете получать эти куски данных максимально быстро и независимо для каждого из клиентов, в отличие от синхронного режима. При интенсивной нагрузке на многопроцессорной машине это может привести к существенному приросту производительности ( в разы ).
Да пребудет с тобою сила
Re[3]: Синхронная и асинхронная работа с сокетами
От: Valentin Nechayev Украина http://netch80.dreamwidth.org/
Дата: 31.07.06 07:42
Оценка:
Здравствуйте, Minimaxus, Вы писали:

N>>Асинхронная обязательна если нет чётких соединений разделяемых на разные сокеты, всё идёт через один сокет. Это типично для UDP серверов (например, DNS или SIP). Для TCP иногда тоже используется асинхронная организация (на Unix типичный пример — innd), но это нетипично.

M>В каких ситуациях один сокет используется? В каких 2 и почему именно так?

Я вообще-то под "один" имел в виду что их количество константно, а не зависит от количества клиентов. Конечно, бывает два или три — например, named держит один сокет серверным на порту 53, а второй — клиентским (если не переопределено в конфиге) на порту из непривилегированного диапазона, для своих запросов. Принципиально это картину не меняет: порождать по сокету на клиента тут невозможно в принципе.
The God is real, unless declared integer.