Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы 41-50.docx
Скачиваний:
0
Добавлен:
25.09.2019
Размер:
95.79 Кб
Скачать

46). Синхронные и асинхронные функции Windows Socket - необходимость применения, возможности.

Synchronous Winsock

Синхронные Window Sockets API смоделированы на базе стандартных Berkeley Sockets API. Совместимость между этими двум программными интерфейсами (API) очень полезна. Особенно тогда, когда более старые куски unix-кода должны быть портированы под Windows.

Вообще, синхронные функции Window Sockets API направлены на процедурное программирование, используя блокирующие сокеты. Программы читают и пишут в сокеты в блокирующей манере, целиком полагаясь на операционную систему. Синхронные API работают лучше в command-line ориентированных многозадачных системах типа Unix. Это не лучший выбор для Windows.

Для решения проблем блокирующих вызовов в ориентированном на события Windows, Winsock API имитирует блокирующие вызовы через использование blocking hook, который содержат цикл обработки событий. К сожалению, такая эмуляция блокирующих вызовов Window Sockets имеет некоторые ограничения. В частности, только один блокирующий вызов может быть активным в данный момент. Эти ограничения напрямую ударяют по пользовательскому интерфейсу программы.

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

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

Чтобы предотвратить это событие, программа Windows, использующая синхронные блокирующие API, должна убедиться, что следующая сетевая операция не может быть запущена, пока программа находится в блокирующем режиме. Программа должна отключать все элементы меню и комбинации клавиш, которые могут привести к запуску другой сетевой операции, а это сложный процесс, особенно если путей много, или полностью отключать пользовательский интерфейс от получения сообщений от мыши и клавиатуры и показывать курсор - песочные часы.

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

Во втором случае пользователь оказывается перед курсором - песочными часами в ожидании завершения сетевой операции, когда мог бы в это время выполнять полезную работу. Многозадачная среда Windows более эффективна, чем однозадачная, поскольку сеть занята.

В обоих случаях невозможно выполнять две сетевые операции в одно и то же время в одном приложении. Пользователь не может одновременно отправлять письмо и проверять наличие новых писем на сервере.

Проблема синхронных Window Sockets API может быть решена двумя способами. Оба с использованием неблокирующих сокетов. Первый метод заключается в том, что создаются неблокирующие сокеты и функцией select() проверяют состояние интересующего сокета. Затем из сокетов читаются и записываются доступные данные или данные, которые могут быть помещены в очередь для передачи. Тем не менее, чтобы избежать проблем блокирующих вызовов, функция sеlect() должна быть вызвана с параметром timeout равным нулю, что приводит к неблокирующей операции. Проще говоря, сама функция select() должна быть вызвана так, чтобы не запереть систему, чтобы поддерживать свою очередь сообщений и в то же время позволить сообщениям Windows достигать ядра системы.

Несмотря на то, что этот код работает, это жалкое решение. Будет сжигаться вхолостую время CPU, в то время как ничего эффективного выполняться не будет - в цикле будет выполняться функция select(). Этот способ слишком не экономно распоряжается ресурсами системы и непригоден в событие - ориентированной операционной системе Windows.

Более эффективное решение всех проблем блокирующих сокетов - это использование асинхронного расширения Window Sockets API.

Тут вы можете оставить комментарий к выбранному абзацу или сообщить об ошибке.

Оставленные комментарии видны всем.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]