Читайте также:
|
|
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.
Дата добавления: 2015-01-30; просмотров: 32 | Поможем написать вашу работу | Нарушение авторских прав |