Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];

Вниз

Socket ы через Event ы   Найти похожие ветки 

 
CyberFreak   (2004-01-13 02:45) [0]

Поделитесь опытом, в чем приумущество сабжа. Когда следует их использовать? И в каком месте собственно ловить эти Event"ы.


 
Rouse_ ©   (2004-01-13 08:39) [1]

9.2.8. Функции select и WSAAsyncSelect
Функция select предназначена для того, чтобы один процесс мог контролировать состояние сразу нескольких сокетов. Функция select позволяет контролировать сокеты по чтению, записи и ошибкам. В Winsock существует асинхронный аналог select, под названием WSAAsyncSelect. Функция WSAAsyncSelect является основной функцией Winsock, способной выполнять не блокирующие операции на сокетах.

В сценарии блокирующего вызова (который был рассмотрен на примере гесv) программа могла вызвать WSAAsyncSelect, чтобы перевести сокет в не блокирующий режим работы. WSAAsyncSelect – единственная в наборе Winsock, принимающая в качестве параметра дескриптор сокета. Основное различие между select и WSAAsyncSelect состоит не в том, что последняя асинхронна, а в том, что только первая способна следить сразу за несколькими сокетами. WSAAsyncSelect способна работать с набором сокетов, однако только после того, как будет вызвана столько раз, сколько сокетов имеется в этом наборе. Другими словами, она должна вызываться с каждым сокетом, за состоянием которого программа желает наблюдать. WSAAsyncSelect требует, чтобы ее параметром являлся только один дескриптор сокета. Функция WSAAsyncSelect иллюстрируется своим прототипом:

int PASCAL FAR WSAAsyncSelect(SOCKET s, HWND hWnd, unsigned int wMsg,long lEvent);

Первый параметр WSAAsyncSelect – дескриптор сокета, за состоянием которого идет наблюдение. Последний, четвертый параметр является битовой маской, определяющей те события, за которыми мы желаем наблюдать. В таблице 9.14 содержатся возможные варианты параметра lEvent.

Таблица 9.14

Значения napaмeтpa функции WSAAsyncSelect, определяющего,
за какими событиями в сокете происходит наблюдение

Константа Описание
FD_READ Извещение о готовности для чтения
FD_ WRITE Извещение о готовности для записи
FD_ООВ Извещение о поступлении данных вне диапазона
FD_АССЕРТ Извещение об установке входящего соединения
FD_CONNECT Извещение об установившемся соединении
FD_CLOSE Извещение о закрытии сокета

Для наблюдения за комбинацией событий в сокете вышеуказанные значения можно совмещать при помощи операции побитового ИЛИ (OR). Предположим, что необходимо, чтобы Windows посылала сообщение по прибытии данных в сокет и когда сокет готов для передачи данных (для записи). В этом случае в качестве параметра WSAAsyncSelect указывается следующая комбинация: (FD_READ | FD_WRITE). Как только статус сокета станет истинным (true), например, в сокете появятся данные для считывания, Windows пошлет сообщение главной процедуре программы (той же самой, что обрабатывает класс сообщений WM COMMAND). Второй и третий параметры функции WSAAsyncSelect такие же, как и в любой функции Windows. wMsg определяет посылаемое сообщение, а hWnd – дескриптор объекта (окна) получателя сообщения.

Как только в сокете произойдет ожидаемое событие, Windows пошлет сообщение стандартного формата. Стандартный формат сообщения Windows включает дескриптор окна, идентификатор сообщения и два параметра сообщения (16- битный и 32-битный). 16-битный параметр сообщения описывает дескриптор сокета, в котором произошло событие, а первые шестнадцать битов 32-битного – само событие. Старшие 16 битов содержат возможное сообщение об ошибках. Вообще, в силу ориентированной на сообщения природы Windows, функция WSAAsyncSelect весьма важна. Возможность контролировать состояние одновременно нескольких сокетов требуется во многих случаях. Например, это нужно для сервера, который должен наблюдать за приходом новых запросов, обрабатывая текущий запрос клиента.

Вызов функции WSAAsyncSelect переводит сокет в не блокирующий режим работы. Предположим, например, что необходимо вызвать функцию recv, не рискуя при этом заблокировать программу. Для этого нужно создать и соединить сокет при помощи функций socket и connect. Далее, вместо вызова recv, нужно вызвать WSAAsyncSelect со следующими четырьмя параметрами:

дескриптор сокета;
окно для принятия сообщения;
идентификатор посылаемого сообщения;
сетевое событие, за которым нужно наблюдать (в нашем случае, FD_READ).
Другими словами, функция WSAAsyncSelect указывает Windows на необходимость информировать программу о готовности сокета к чтению данных. Как только сокет получит сетевые данные, Windows пошлет соответствующее сообщение, заданное при вызове WSAAsyncSelect. Как только обработчик сообщений получит его, у программы появится возможность вызвать recv для данного сокета. Поскольку данные уже получены сокетом, функция recv никак не может блокировать программу, скорее всего она сразу вернет ожидающие считывания данные. Такая схема также не свободна от ряда недостатков, и пользовательская программа должна справляться с ними. Как бы то ни было, применение WSAAsyncSelect позволяет сделать вызов recv не блокирующим.


 
Polevi ©   (2004-01-13 09:11) [2]

>Rouse_ ©   (13.01.04 08:39) [1]
вообщето вопрос был о WSAEventSelect
>CyberFreak   (13.01.04 02:45)
работает быстрее, ловить - как любой другой объект синхронизации - WaitFor.. ф-ями


 
Rouse_ ©   (2004-01-13 09:30) [3]

> [2] Polevi ©   (13.01.04 09:11)
Вполне возможно что и про WSAEventSelect...
Я подумал о событиях типа FD_READ ...

Посмотрим, что скажет автор вопроса...


 
CyberFreak   (2004-01-15 03:38) [4]

Да, именно WSAEventSelect... И наскока я понимаю вызов WaitFor замораживает поток, в котором его вызывают, так что придется выносить в отдельный... А если сокет один, имеет ли это смысл? Взять, вынести обычный блокирующий в отдельный поток и пусть он там себе колбасится. Или я ошибаюсь?


 
Digitman ©   (2004-01-15 08:30) [5]


> наскока я понимаю вызов WaitFor замораживает поток, в котором
> его вызывают, так что придется выносить в отдельный


Выносить или не выносить - решать тебе.
Но ничто не мешает вместо WaitFor-вызова использовать MsgWaitFor-вызов. При этом вызывающий поток будет получать управление всякий раз не только при наступлении сигнальных событий ивентов, но и при получении win-сообщений, адресованных код.потоку и/или окнам, им созданным.


 
Digitman ©   (2004-01-15 08:31) [6]

Удалено модератором
Примечание: Дубль...


 
Digitman ©   (2004-01-15 08:33) [7]

Удалено модератором
Примечание: Дубль...


 
Digitman ©   (2004-01-15 08:34) [8]

Удалено модератором
Примечание: Дубль...


 
Digitman ©   (2004-01-15 08:35) [9]

Удалено модератором
Примечание: Дубль...


 
CyberFreak   (2004-01-15 17:01) [10]

Ok... но я все не могу догнать, куда, например в обычном VCL-приложении, запихнуть этот самый MsgWaitFor...?


 
Digitman ©   (2004-01-15 19:02) [11]


>  запихнуть


"запихнуть" - не знаю

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


 
CyberFreak   (2004-01-15 19:46) [12]

Ну вот если у меня основной поток VCL-приложения в этом заинтересован, куда надо зап... хм... где должен происходить вызов MsgWaitForMultiplyObjects? В OnCreate формы, в OnPaint, в OnShow?.. Может действительно звучит глупо, но я четно не могу догнать.


 
Digitman ©   (2004-01-16 09:04) [13]

В OnCreate() :
создаешь гнездо, вызываешь WSAEventSelect() и пр. и пр.
в конце обработчика вызываешь PostMessage(Handle, MY_MESSAGE, 0, 0);

TMyForm = class(TForm)
...
 procedure MsgMyMessage(var Message: TMessage); message MY_MESSAGE;
end;

procedure TMyForm.MsgMyMessage(var Message: TMessage); message MY_MESSAGE;
begin
 while True do
   case MsgWaitForMultipleObjects(1, FhSocketEvent, False, FEvntWaitTimeout, QS_ALLINPUT) of
      WAIT_OBJECT_0:      // обработка трансп.событий;
      WAIT_OBJECT_0 + 1:  // обработка сообщений
               while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
                 begin
                   TranslateMessage(Msg);
                   DispatchMessage(Msg);
                 end;
;
      WAIT_TIMEOUT:       // обработка таймаута ожидания событий или сообщений;
      WAIT_ABANDONED:     Break; //выход из цикла - ивент был закрыт
   end;
end;


 
Slym ©   (2004-01-16 13:49) [14]

1. Эвенты пользуются когда необходимо работать без окна обработки (например в Сервисе).
2. Сообщения штука ненадежная! а если вирус поставит хук на ваши мессаги? кердык и вирус замаскировался под легальную прогу. а Изменение Эвента перехватить проблематично или даже невозможно!
P.S. С маскировкой есть ряд проблем (например хендл сокета в другом процессе), но и они решаемы (внедрением в адресное пространство).
3. Эвенты работают Быстрее! за счет того что система сообщений может иметь низкий приоритет и она будет медленнее постить сообщения и еще проходить кучу ловушек! а эвент мигнул и процесс стартанул! никаких лишних препятствий!
4. С Эвентами каждый сокет может работать в отдельном потоке: recv в оконной процедуре все равно тормознет поток (не заблокирует) так что другие встанут в очередь за этой оконной процедурой. а с разными потоками сокеты будут конкурировать за процессорное время, т.е. работать одновременно



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2004.03.28;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.029 c
7-1073425700
Cure
2004-01-07 00:48
2004.03.28
GetKeyNames


1-1078842668
akosko
2004-03-09 17:31
2004.03.28
Многоязыковая поддержка


6-1073907626
Anatolik
2004-01-12 14:40
2004.03.28
kak c помошью компанента WebBrowser можно соединится через


14-1078228066
TALLA
2004-03-02 14:47
2004.03.28
Почему из Execute при вызове DdeClientConv1.SetLink( a , b )


11-1056812998
Dimaxx
2003-06-28 19:09
2004.03.28
Про ZLIB





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский