На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Соблюдайте общие правила форума
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Указывайте точные версии Delphi и используемых сетевых библиотек.

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

Внимание:
попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Krid, user posted image Rouse_

Модераторы: Krid, Rouse_
  
> Что значит блокирующие и неблок. Socket? , Ну как мне программировать под бл. или небло. ?
    Не как с головы не уходит прочитал заголовок
    про это а самой статьй нету так и не понил?
      Arazel, неплохо было бы почитать элементарные справочники по сокетам, чем сразу на форум идти. Точно об этом написано у Марко Кэнту.
      Сообщение отредактировано: Rouse_ -
        Когда то давно я уже обьяснял - чтож, повторюсь пожалуй :)

        Блокирующий режим:
        Как видно из названия, все операции, производимые с сокетом в момент установленного соединения, являются синхронными основному потоку приложения, из-за чего при вызове любой функции (отвечающих за передачу, прием данных или (в некоторых случаях) контроль состояния сокета), продолжение работы приложения приостанавливается дотехпор, пока функция не вернет результат. Чем отличается применение данного режима в приложении? Данный режим транспорта обычно применим, когда нужно приостановить работу приложения до окончательного получения данных, т.н. линейное программирование... Обычно вся работа с данным режимом сокета выносится с отдельный поток, во избежания остановки ЦВС главного приложения... Чаще всего данный тип транспорта применяется в консольных приложением, так как не имеет событий, связанных с обменом данных...
        Заметь работа серверного сокета без потоков практически невозможна - поэтому в TServerSocket используется stThreadBlocking...

        Неблокирующий режим:
        В данном режиме выполнение операций с сокетом не приостанавливает работу приложения. О завершении работы функций приложение уведомляется. Данный режим реализован как альтернатива блокирующему режиму в потоке (т.е. при данном режиме поток попросту бесполезен). Так как уведомление о завершении выполнения приходило позже, то для реализациии получения данного уведомления, программист должен был озаботится о механизме - который и будет принимать данное уведомления. Вот тут уже и начинаются понятия ООП, такие как события (OnWrite, OnRead и т.д.).

        Какой из режимов применять, каждый выбирает по себе. Не хочешь работать с потоками - работай с семафорами (Event). Не хочешь работать с ними - тогда работай через потоки

        Я обычно придерживаюсь Winsock расширения сокетов Беркли под названием "Асинхронный режим сетевого транспорта".
        Данный вариант представляет из себя тотже неблокирующий режим, но отличие его от классического в том, что не нужно озаботится о механизме получения уведомлений. Данную часть на себя берет сама операционная система и именно она и будет оповещать тебя о произошедшем событии, посредством отправки оконных сообщений твоему приложению которые тебе нужно будет обработать (банальный SendMessage вызываемый с ее стороны)
          Arazel
          Это из UNIX - а оттуда идет вся сокетная идеология
          "Проблема блокирования
          Принципиально операции ввода-вывода в среде UNIX-подобных ОС могут соответствовать пяти разным моделям исполнения – блокирующей, неблокирующей, с мультиплексированием, управляемой сигналами и асинхронной. Первые четыре модели реализуют идею синхронного ввода/вывода. Для точного понимания проблемы блокирования при выполнении сетевых операций ввода/вывода сформулируем само понятие блокирования.
          Что же понимать под блокированием и что именно блокируется? Рассмотрим вариант применения системного вызова connect().
          Функция connect() является системным вызовом и переводит процесс из состояния программы в состояние ядра, тем самым приостанавливая (блокируя) дальнейшее исполнение программы пользователя до возврата управления из ядра на следующую за connect() инструкцию. Время приостанова в принципе неизвестно – у connect() нет явного параметра timeout (хотя мы выше уже отмечали, что этот timeout устанавливается самим ядром), поэтому ожидание может занять довольно большое по "компьютерным меркам" время, за которое можно было бы выполнить довольно много последующих инструкций.
          Отдельные системные вызовы операций на сокетах блокируют программу в случае, если удаленный процесс не осуществил ожидаемую операцию: connect(), accept(), write(), read() и т. д. Это врожденный недостаток использования блокирующих сокетов. При создании сокета ядро сразу устанавливает его в режим блокирования.
          Таким образом, если что-то читается из сокета, например, вызовом read(), то управление вернется в программу только в том случае, если пришли реальные данные по этому соединению, либо произошла ошибка (например, разрыв связи).
          Поэтому во многих случаях сетевых действий выгодно работать с неблокирующими сокетами. Как уже говорилось, сокет всегда создается блокирующим. Однако в UNIX-подобных системах существуют очень гибкие механизмы борьбы с этого типа блокированием. С их помощью сокет можно объявить (специальными функциями управления операциями ввода/вывода) как неблокирующий, и выполнение системного вызова для него заставит ядро вернуть управление в процесс сразу же после вызова, завершая тем самым инициированную операцию ввода/вывода параллельно с выполнением процесса.
          В модели неблокирующего ввода/вывода применяется несколько альтернативных идеологий: постоянного опроса ядра (как правило в цикле), мультиплексирования, управления сигналом или асинхронная.
          Реальные сетевые программы практически никогда не используют блокирующие функции: это было бы слишком медленно. Или, точнее, могут использовать блокирующий read(), но только удостоверившись в том, что ему есть что прочитать посредством предварительного вызова select().
          Единственное исключение – это вызов connect(), он все равно остается блокирующим, т. к. к нему нельзя напрямую применить идеологию вызова select(). Это становится понятным, если вспомнить, что connect() работает с очередью установления соединения, а не с очередью данных. Вызов функции connect() для установления прямого соединения с удаленным хостом блокирует программу в состоянии ядра до тех пор, пока низлежащий транспортный уровень не установит соединения и не информирует об этом ядро системы."
          Это - о синхронных сокетах Windows
          "3.6.2. Синхронные сокеты WinSock API
          Синхронные функции API Window Sockets фактически являются клоном стандартных функций Berkeley Sockets API, что особенно наглядно видно при просмотре списков экспорта для winsock.dll (16-ти битная версия, сейчас практически не используется), wsock32.dll и ws2_32.dll (приложение 8). Совместимость между этими двум программными интерфейсами (API UNIX и Windows сокетов) позволяет писать сетевые приложения под Windows в чистом стиле Беркли-сокетов, а также полезна при портировании более старых фрагментов UNIX-кода в Windows. Вообще, синхронные функции API Window Sockets ориентированы на процедурное программирование, используя блокирующие сокеты.
          Использование синхронного API Window Sockets решается с помощью неблокирующих сокетов. Как мы уже знаем, сокет можно тем или иным способом объявить неблокирующим и функцией select() проверять состояние интересующего сокета (см. раздел 2.6.7). Затем после проверки соответствующих наборов сокетов производятся необходимые операции. Чтобы избежать проблемы с блокирововкой в самой функции sеlect(), она должна быть вызвана с параметром timeout равным нулю. То есть сама функция select() должна быть вызвана так, чтобы не запереть систему, поддерживать свою очередь сообщений и в то же время позволить сообщениям Windows достигать ядра системы. Для этого может использоваться код:
          Листинг 3.5 Выборка сообщения из системной очереди
          struct timeval timeout = {0, 0};
          while (!select(..., &timeout)) {
          if (PeekMessage(...)) /* Выборка сообщения из системной очереди */
          {
          TranslateMessage(...);
          DispatchMessage(...);
          }
          }
          Следует отметить и проблемы, связанные с определением дескриптора окна, в котором исполняется этот код. Так как это консольный вариант, определение его возможно только с помощью специальной функции WIN32 API FindWindow(), находящейся в user.dll (user32.dll), при этом надо знать имя окна исполнения (его лучше задать самому программисту в коде консольной программы). Если же значение hWnd равно NULL, то функция PeekMessage() будет в цикле проверять все сообщения, что тоже приведет к временным потерям.
          Несмотря на то, что этот код работает, такой вариант далек от оптимального по причине неэффективного использования времени CPU, который будет загружен циклом выполнения функции select() - об этом мы уже упоминали при ее описании во втором разделе.
          Второй метод – это использовать ловушки блокировки – blocking hooks, или, попросту, обмануть операционную систему, перехватив настоящее сообщение и заменив его другим, или выдать сообщение о успешном завершении, в то время как его еще и не было. Ловушка (hook) – это механизм Windows, позволяющий перехватывать события, предназначенные некоторому приложению, до того как эти события до этого приложения дойдут. Перехваченные сообщения можно модифицировать, отслеживать или просто отбрасывать.
          Для решения проблем блокирующих вызовов в ориентированных на события ОС Windows, WinSock API имитирует блокирующие вызовы через использование blocking hook – установки процедуры перехвата, который содержит цикл обработки событий.
          Сетевая Windows-программа вызывает ловушку блокировки только тогда, когда выполнены все следующие условия:
          · функция - именно та, которая способна заблокировать процесс,
          · указанный сокет – блокирующий, и
          · вызов не может быть закончен немедленно.
          Как и в UNIX, Windows-сокет по умолчанию создается блокирующим, но команда FIONBIO функции ioctlsocket() и функция WSAAsyncSelect() (раздел 3.6.3.1) переводят сокет в неблокирующий режим. Если приложение использует только неблокирующие cокеты, используя функции WSAAsyncSelect() и/или WSAAsyncGetXByY() вместо функций select() и getXbyY(), то ловушка блокировки не будет вызываться никогда.
          Такой стиль исполнения блокирующих вызовов WinSock имеет некоторые ограничения. В частности, только один блокирующий вызов может быть активным в данный момент, что существенно влияет на пользовательской интерфейс программы."
          Это - об асинхронных операциях:
          "Асинхронные сокеты WinSock API
          Асинхронная модель ввода/вывода – это одна из главных моделей выполнения операций ввода/вывода в Windows (см. раздел 4.3), поэтому ее использование является наилучшим решением для программирования сокетов под Windows. Она позволяет выполнять одновременно множество сетевых задач без лишней нагрузки на процессор.
          Любая асинхронная функция отвечает только за начало операции — она не ждет ее завершения, за продолжением начатой операции далее наблюдает операционная система. В большинстве ОС принято посылать сообщение о результатах окончания асинхронной операции, и Windows относится именно к таким ОС. Фактически, каждое событие в Windows происходит асинхронно. Когда происходит событие или заканчивается асинхронная операция, Windows посылает сообщение тому объекту (обычно, окну), которое было указано при вызове асинхронной функции.
          Асинхронное расширение WinSock отсылает сообщение окну всякий раз, когда:
          · происходит смена состояния сокета или
          · когда асинхронная функция завершает поиск в сетевой базе данных (см. ниже).
          Индикация смены состояния сокета может выполняться с помощью функции WSAAsyncSelect() или WSAEventSelect() (см. раздел 4.3). Поиск по сетевым базам данных WinSock выполняется функциями типа WSAAsyncGetXByY() (WSAAsyncGetProtoByName(), WSAAsyncGetServByPort() и т. д.). Большинство из стандартных функций Беркли имеет "копию" с похожим названием для асинхронного расширения, но их использование может быть неадекватным."
          Сообщение отредактировано: Oleg2004 -
          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script execution time: 0,0333 ]   [ 16 queries used ]   [ Generated: 21.12.25, 05:22 GMT ]