Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

TServerSocket, TClientSocket. Синхронный и асинхронный, блокирующ [D6, Win95/98, WinME, NT4, Win2k, WinXP]


Страницы:   1 2 3

Анонимщик ©   (2004-04-22 11:33:00) 

Синхронный и асинхронный, блокирующий и неблокирующий.

Что в контектсе сокетов значит "Синхронный и асинхронный, блокирующий и неблокирующий"?
Я почему-то думал, что синхронный режим - тот, что позволяет обеим сторонам общаться,
синхронизируя посылку данных друг другу. Т.е. работа в синхронном режиме подразумевает
некий диалог между ними.
Но вот читаю: "Асинхронными они названы по той причине, что их выполнение связано с
определенным диалогом и ни начало, ни завершение не ограничено какими-либо временными
рамками". Т.е. с точностью до наоборот. Почему так, можно спросить?

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

одна из сторон на время своего посылания данных блокирует другую?
И еще одно. Если режим асинхронный, то тогда нужно выставить тип для сервера - ctThreadBlocking,
а для клиента - ctBlocking? Тогда сервер для каждого клиентского соединения создает поток,
который с этим клиентом и работает. И вот мне не понятно, почему того же нельзя сделать
и для синхронного режима в принципе, т.е. почему нет этой возмодности.

Короче, я все напутал, прошу помочь распутать.

И последнее. Можно ли создавать TClientSocket не в главном потоке? Прочитал, что операционная
система сообщает о событиях для сокета в то окно, с контекстом потока которого сокет связан.
Естественно, в дочернем потоке никакого окна нет. Так дойдет ли куда-нибудь сообщение вообще?
Впрочем, так я уже делал, но, кроме этого, создавал еще и поток, который занимается обработкой
принимаемых/отправляемых данных для этого сокета. И данные приходят и отправляются. Но смутные
сомнения терзают все равно.

Короче говоря, пожалуйста, те, кто знают, пусть разжуют, правильно сформулируют и ответят.


Rouse_   (2004-04-23 23:08:00) [21]

Type Parameter
Syntax {$EXTERNALSYM identifier}

The EXTERNALSYM directive prevents the specified Pascal symbol from appearing in header files generated for C++Builder. If an overloaded routine is specified, all versions of the routine are excluded from the header file.


Piter   (2004-04-23 23:06:00) [22]

А можно попутный вопрос? Зачем нужна директива $EXTERNALSYM ?


Verg   (2004-04-23 19:04:00) [23]

type
 {$EXTERNALSYM u_char}
 u_char = Char;
 {$EXTERNALSYM u_short}
 u_short = Word;
 {$EXTERNALSYM u_int}
  u_int = Integer; {$EXTERNALSYM u_long}
 u_long = Longint;

{ The new type to be used in all
 instances which refer to sockets. }
 {$EXTERNALSYM TSocket}
  TSocket= u_int;


"Гемор", говоришь...


Verg   (2004-04-23 19:01:00) [24]


>  В Делфи7 Борланд вообще их переделала - по новой разбираться
> с ними - пустая трата времени.


Пере.. что? Куда переделала, какие именно "компоненты" переделала?
TSocket - это тип данных из модуля WinSock.pas. По-сути - integer.


Ермак   (2004-04-23 18:44:00) [25]

Вообще рекомендую бросить работать с компонентами типа TSocket - это такой гемор! В Делфи7 Борланд вообще их переделала - по новой разбираться с ними - пустая трата времени. Есть WinSock API, все просто и понятно, я за полчаса с ним разобрался и начал работать. Можно создавать сколько хочешь потоков, хоть с окном, хоть без окна, хоть в сервисе - дело хозяйское, ты все полностью контролируешь и понимаешь. Особенно если поток создавать не тупым TThread, а через Create Thread. Короче, рекомендую WinSock API и вообще код, чистый от компонентов!

Вот хорошая статья: http://book.itep.ru/7/sock_71.htm


Digitman   (2004-04-23 16:48:00) [26]


> Yermek   (23.04.04 16:24) [20]


либо закрыть все активные соединения (в списке Connections) ,прежде чем делать ServerSocket.Close, либо изменить радикальным образом явно неверный алгоритм метода ClientExecute

в любом случае то что творится в ClientExecute
заслуживает детального рассмотрения


Yermek   (2004-04-23 16:24:00) [27]

Как корректно закрыть ServerSocket (stThreadBlocking) если к нкму подключены ClientSocket, при ServerSocket.Close пограмма зависает.


Digitman   (2004-04-23 08:58:00) [28]


> Fantasist ©   (23.04.04 01:39) [17]


> Неблокирующий вызов - это все-таки не вызов процедуры с
> отложенным получением данных путем уведомления (это как
> раз асинхронный вызов), а вызов, который возращается в независимости
> были ли полученны данные или нет


вникни в [3]
как раз об этом я там и сказал
в чем же расхождение ?


> объясняются следствия (работа TClietSocket/TServerSocket
> и их опции), а не факты их порождающие (WinSocket API).


а какая разница, WinSock API или не WinSock API ? оболочка (в виде упомянутых компонентов) или не оболочка ? Суть от этого не меняется. Есть просто некий вызов, он м.б. блокирующим, а может быть и неблокирующим - в зависимости от реализации алгоритмов вызываемого кода. Если внутренний алгоритм вызыв.п/программы предусматривает асинхронные нотификации (тем или иным образом), его можно использовать, а можно и не использовать, если задействован неблок.механизм вызываемого алгоритма.

в случае с оболочкой WinSock API в виде упомянутых компонентов все так же остается в силе

например, тот же вызов метода Open() в неблок.режиме практически немедленно вернет управление, создав перед этим (если требуется) окно, связав окно с гнездом и запустив механизм коннекта...

чтобы получить асинхр.извещение о факте коннекта, достаточно назначить обработчик события OnConnect ... если же асинхр.извещение о факте коннекта не требуется, придется циклически опрашивать состояние св-ва Active, при этом не забывая в каждой итерации на время передавать управление диспетчеру оконных сообщений (коль мы точно знаем, что внутренняя нотификация как таковая все равно задействована, хотим мы этого или нет , и именно - оконная)


Polevi   (2004-04-23 07:59:00) [29]

>Yermek   (22.04.04 21:46) [16]
отдельный поток для асинхронного режима как раз не обязателен для каждого нового клиента. достаточно одного кодового потока, который будет принимать уведомления от winsock о неких событиях (получение данных, акцепт клиента, дисконнект) и чтото делать. главное чтобы эти действия занимали как можно меньше времени, чтобы не блокировать транспорт


Fantasist   (2004-04-23 01:39:00) [30]


> Digitman ©   (22.04.04 12:06) [1]


 Не совсем могу согласиться с приведенной аналогией блокирующего/неблокирующего вызова. Неблокирующий вызов - это все-таки не вызов процедуры с отложенным получением данных путем уведомления (это как раз асинхронный вызов), а вызов, который возращается в независимости были ли полученны данные или нет. Сравнить можно с проверкой е-мыльного ящика:

1. Блокирующий. Ты открываешь почтового клиента, и ничего не делаешь, пока в нем не появиться новое письмо. После этого ты его читаешь и начинаешь что-то делать.

2. Неблокирующий. Открываешь почтового клиента и смотришь: если есть письмо - читаешь его и начинаешь что-то делать, если нет, продолжаешь заниматься чем-то другим.

 Хочу сказать, что объяснения приеведенные в это треде весьма запутывающе. Думаю как раз из-за того, что объясняются следствия (работа TClietSocket/TServerSocket и их опции), а не факты их порождающие (WinSocket API). Я бы реккомендовал поизучать работу с сокетами непосредственно на уровне API, тогда станет понятно, что за "асинхронный режим работы", и что делает stThreadBlocking и stNonBlocking. А так же может выясниться, что TClietSocket/TServerSocket вовсе и не нужны. Со мной во всяком случае так и произошло на серверной части. Оказалось, что мне  удобнее и надежнее написать собственную реализацию класса серверного сокета используя API, нежели использовать готовую от Delphi.


Yermek   (2004-04-22 21:46:00) [31]

"Краткость сестра таланта"

Sorry за назойлевость.
Как в асинхронном элементарно текстовое сообщение отправить от сервера к клиенту и наоборот, я в курсах что создается отдельный поток на сервере при каждом новом подключении клиента... а можно пример.


Polevi   (2004-04-22 21:29:00) [32]

> [14] Yermek   (22.04.04 20:53)
нет


Yermek   (2004-04-22 20:53:00) [33]

А можно такой вопрос:

Обязательно ли, если на ServerSocket ServerType=stThreadBlocking то и в ClientSocket обязательно должно быть NonBlocking.


Анонимщик   (2004-04-22 15:30:00) [34]

Во, за это спасибо, буду пытаться.


Digitman   (2004-04-22 15:12:00) [35]

при stThreadBlocking перевести гнездо в неблок.режим можно двумя способами :

1) в режим оконных нотификаций - вызовом WSAAsyncSelect, при этом придется "ручками" создать окно (ибо оно по умолчанию в stThreadBlocking не создается) и только после этого связать хэндл окна с хэндлом гнезда вышеупомянутой ф-цией

2) в режим событийных нотификаций - вызовом WSAEventSelect, при этом придется "ручками" создать объект Event и только после этого связать хэндл объекта Event с хэндлом гнезда вышеупомянутой ф-цией

далее, в зависимости от 1 или 2, в доп.потоке организуется либо цикл ожидания/выборки/диспетчеризации оконных сообщений либо цикл ожидания сигналов объекта Event


Digitman   (2004-04-22 15:06:00) [36]

stNonBlocking не создает доп.потоков, но создает единственное окно (для приема нотификаций от своих гнезд, ассоциированных с активными клиентами) и устанавливает режим асинхр.нотификации вызовом WSAAsyncSelect

stThreadBlocking не создает никаких окон, но создает для каждого активного соединения отдельный код.поток (т.н., транспортный поток), передавая этому потоку параметром новый объект-гнездо ClientSocket: TServerclientWinSocket, отражающий транспортный контекст соединения с данным активным клиентом и инициализированный по умолчанию для работы в блокирующем режиме


Polevi   (2004-04-22 14:53:00) [37]

>Анонимщик ©   (22.04.04 14:52) [9]
F1 WSAAsyncSelect


Анонимщик   (2004-04-22 14:52:00) [38]

А чем же тогда stThreadBlocking и stNonBlocking отличаются вообще?
Кроме того, каким образом эту асинхронность включить, извиняюсь на назойливость.


Digitman   (2004-04-22 14:47:00) [39]


> обработка будет происходить только в одном потоке сервера


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

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


Анонимщик   (2004-04-22 14:31:00) [40]

Значит, я ошибался, когда считал, что, если выставить тип сервера в stThreadBlocking, то тогда отправка сообщений будет происходить без промедления (в смысле, функция якобы тут же отрабатывает).
Но если поставить nonBlocking, то тогда обработка будет происходить только в одном потоке сервера. Так? А это очень неудобно. Хотелось бы с каждым клиентом иметь свой поток.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо