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

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

TIdTCPServer & TIdTCPClient не могу поймать отсоединение клиента [D7, WinXP]


Serguar ©   (2004-08-02 14:52:00) 

Здравствуйте.
Ни как не могу поймать отсоединение клиента на сервере. Событие ServerConnect при подключении клиента срабатывает четко. Когда на клиенте делаю Client.Disconnect он (клиент) тоже пишет что отсоединился, а на сервере в методе ServerDisconnect ни какой реакщии. Че делать?
Заранее благодарен.


Sh@Dow   (2004-09-07 07:58:00) [1]

Калашников урод. тебе бы такие проблемы, ты сам бы и отсосал.


Калашников   (2004-08-04 08:14:00) [2]

ОТСОСИ И ВСЁ ПОЛУЧИТЬСЯ (с) Калашников


Serguar   (2004-08-03 11:50:00) [3]

Черт возьми. Все оказалось гораздо проще. Обидно. Спасибо за помощь. Все понял.


Reindeer Moss Eater   (2004-08-03 11:10:00) [4]

> 1. Не поможет.
Уже работает
> 2. Не проще.
Научи как проще


Не поможет потому, что если сервер не читает, то ничего он не примет от клиента.

А если сервер читает/пишет, то никаких уведомлений на прикладном уровне типа "я ухожу" - вообще просто не надо.


Digitman   (2004-08-03 10:47:00) [5]


> Serguar   (03.08.04 10:30) [15]



> перед отсоединением клиента, посылаю серверу сообщение об
> отсоединении. Тот в методе OnExecute отсоединяет его, что
> вызывает событие OnDisconnect


это называется "в соседнюю комнату через Китай"

ты же все равно в OnExecute будешь вызывать какие-то Read-методы !

пока клиент активен и ничего не посылает, Read-метод "висит" (блокирует дальнейшее выполнение операторов тела обработчика) на время, равное указанному таймауту .. если в период таймаута ожидания ввода клиент по прежнему активен и ничего не посылает, Read-метод завершается успешно .. если же в период таймаута ожидания ввода клиент отсоединился, Read-метод возбудит исключение, и если ты не обработаешь это исключение, то его обработает сам PeerThread, вызвав Connection.Disconnect ... если же ты сам обрабатываешь исключение, то ты сам и должен в except-блоке вызвать Connection.Disconnect ! И все !! и никаких проблем и выкрутасов !!


Serguar   (2004-08-03 10:30:00) [6]


> Reindeer Moss Eater



> 1. Не поможет.

Уже работает


> 2. Не проще.

Научи как проще


Reindeer Moss Eater   (2004-08-03 09:53:00) [7]

Все. Я понял. Тогда уж проще будет сделать так: перед отсоединением клиента, посылаю серверу сообщение об отсоединении

1. Не поможет.
2. Не проще.


Serguar   (2004-08-03 09:43:00) [8]


> Digitman


Все. Я понял. Тогда уж проще будет сделать так: перед отсоединением клиента, посылаю серверу сообщение об отсоединении. Тот в методе OnExecute отсоединяет его, что вызывает событие OnDisconnect. Хотел сразу так сделать. Просто не сразу понял как работает метод OnDisconnect на сервере. Спасибо за участие.


Digitman   (2004-08-03 08:59:00) [9]


> там есть пример IdTCPDemo


обрати внимание, что в этом примере в обработчике OnExecute есть методы записи/чтения, при блокирующемвыполнении которых ситуация дисконнекта кака раз и обнаруживается, что приводит к исключению, в обработчике по умолчанию которого и вызывается метод PeerThread.Connection.Disconnect (а в теле метода Disconnect возбуждается событие OnDisconnect)


Serguar   (2004-08-03 08:34:00) [10]

В поставке Indy9 есть каталог с примерами. Так вот там есть пример IdTCPDemo. Загружаю, смотрю: все работает четко. При отключении клиента, на сервере в memo добавляется строчка уведомляющая об отсоединении клиента именно в методе OnDisconnect. Буду разбираться.


Digitman   (2004-08-03 08:16:00) [11]


> зачем тогда на сервере вообще нужен обработчик OnDisconnect?


чтобы выполнить какие-то специфические действия при (см.цитату из справки) TIdPeerThread attempts to disconnect from a TCP server


Serguar   (2004-08-03 07:45:00) [12]

> Digitman

> поскольку после отсоединения партнера по его инициативе любой метод чтения/записи объекта PeerThread.Connection вызовет исключение, ты можешь обработать его здесь же и установить PeerThread.Connection.Connected = False

Так мне что, для того что бы проверить не отсоединился ли клиент, нужно каждый раз делать чтение/запись? А зачем тогда на сервере вообще нужен обработчик OnDisconnect?

Вот код OnExecute сервера:

procedure TMainForm.TCPServerExecute(AThread: TIdPeerThread);
begin
 if Not AThread.Connection.Connected then
   ShowMessage('Client disconnected...');
end;
При вызове на клиенте
 if TCPClient.Connected then begin
   TCPClient.Disconnect;
 end
на сервере вышеописанный код не проходит.


Digitman   (2004-08-02 17:09:00) [13]


> Serguar   (02.08.04 16:28) [7]


OnDisconnect is an event handler for a TIdServerThreadEvent. OnDisconnect occurs when the TIdPeerThread attempts to disconnect from a TCP server.

OnExecute вызывается циклически до тех пор, пока св-во
PeerThread.Connection.Connected = True

в обработчике OnExecute ты выполняешь чтение/запись с использованием объекта PeerThread.Connection

поскольку после отсоединения партнера по его инициативе любой метод чтения/записи объекта PeerThread.Connection вызовет исключение, ты можешь обработать его здесь же и установить PeerThread.Connection.Connected = False

можешь и не обрабатывать исключение, тогда его обработает сам TIdPeerThread и сам установит PeerThread.Connection.Connected = False

только при таком механизме и логике ты получишь событие OnDisconnect


> Memo.Lines.Add


а вот этого вообще нельзя делать без синхронизации с осн.трэдом


Serguar   (2004-08-02 16:28:00) [14]

Просто к CodeSite привык уже. Ставлю BreakPoint в обработчик OnDisconnect -> туда даже не попадает.

procedure TMainForm.TCPServerDisconnect(AThread: TIdPeerThread);
begin
 Memo.Lines.Add(Format('%s> Client disconnected: %s', [FormatDateTime('dd.mm.yyyy hh:mm:ss', Now), AThread.Connection.LocalName]));
end;


Digitman   (2004-08-02 16:25:00) [15]


> Для отладки использую CodeSite2


а чем обосновано упразднение тобой встроенного в Делфи дебагера ?


Serguar   (2004-08-02 16:06:00) [16]

>MetalFan

TIdTCPServer.OnExecute
Event handler for peer thread execution. Перевожу как умею: Обработчик события при запуске нитки (вызов метода TIdPeerThread.Run). Это из help. Я так понял, что использую этот метод при обмене данными между клиентом и сервером, а для перехвата событий connect/disconnect имеются специальные методы.

> Digitman
Для отладки использую CodeSite2. В обработчике события вставляю строчку типа printf в Си. Так вот в viewer'e этого инструмента идет подсчет срабатываний.


Digitman   (2004-08-02 15:54:00) [17]


> на сервере в методе ServerDisconnect ни какой реакщии


тогда приводи обработчик события OnDisconnect


> OnExecute: срабатывает аж по 138 раз


а сколько, по-твоему, должно быть ? и на основании чего у тебя некие предположения по сему поводу ?


MetalFan   (2004-08-02 15:49:00) [18]

а вы понимаете, зачем вообще нужен OnExecute на IdTCPServer ?


Serguar   (2004-08-02 15:39:00) [19]

Да я собственно OnExecute пока ничего не делаю. Пока просто проверяю connect/disconnect. Попробовал просто распечатывать текстовую строчку в методе OnExecute: срабатывает аж по 138 раз при нажатии в клиенте connect/disconnect. Как тогда фильтровать?


Digitman   (2004-08-02 14:56:00) [20]


> Че делать?


привести сюда код обработчика события OnExecute


Наверх

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