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

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

ServerSocket проверка на физический разрыв сети [D6, Win2k]


Вячеслав Чернов ©   (2002-07-04 13:48:00) 

Может кто сталкивался с периодической проверкой подключения клиента на предмет доступности. Стрессовая ситуация - выдернут сетевой шнурок и Socket.Connectedвозвращает true.
Это глюк или нормальная работа ServerSocket.


Digitman   (2002-07-05 16:10:00) [1]

1. Ну а где же у тебя обработчик OnClientError() ? Как же ты собираешься перехватывать исключительные ситуации при обращении к уже несуществующему физически транспортному каналу с клиентом ?

2. Что значит "срабатывает" или "не срабатывает" ?
Ты программист или где ? Поставь брейкпойнт на строчке "проверки подключения", поймай брейкпойнт в момент, когда клиент заведомо "оборван" и почитай средствами отладчика свойство User[i].Socket.RemoteAddress ! Чему оно равно ? Возбуждает ли дебагер исключение при этом ?

3. Все, что делает свойство TCustomWinSocket.Connected - возвращает значение приватного поля TCustomWinSocket.FConnected.
Которое ,в свою очередь, становится True при установлении успешного коннекта с партнером, и сбрасывается в False при вызове метода TCustomWinSocket.Disconnect().

TCustomWinSocket.Disconnect() вызывается автоматически :
- в деструкторе объекта TCustomWinSocket (ты его вызывал, деструктор ?);
- перед вызовом обработчика OnDisconnect() (когда соединение корректно закрывается по инициативе партнера);
- при возбуждении классом TCustomWinSocket исключения, связанного с отказом одной из гнездовых API-ф-ций (связанных, кроме всего прочего, и с обращением по чтению/записи к проблемному транспортному каналу)

В этом есть какие-то сомнения ? Можешь проверить всю эту логику (да и давно надо было бы !) в модуле scktcomp.pas.

Ну что ? Дальше ? Или таки убедил я тебя в некорректности твоего варианта проверки активности соединения ?


ChernoVVV   (2002-07-05 12:42:00) [2]

Инициализация ->ServerSocket.ServerType := stNonBlocking;
OnConnect(Server) ->User( TUser(TObject+Socket)).Socket( TCustomWinSocket) := Socket( OnConnect(Socket));(add in list)
Проверка подключения -> (User[i].Socket=nil)or(not User[i].Socket.Connected)or(User[i].Socket.RemoteAddress) then User[i].Free(del in list);<- это как раз и не срабатывает !


Digitman   (2002-07-05 12:05:00) [3]

Ага ! Таки поймал ты исключение ?) Собственно, это вот и ответ на твой вопрос по клиентской стороне : "молчит" клиент - ни черта он не получит никаких извещений о том, что "шнурок" у сервера "оторвали" ...

А вот чтобы ответить на аналог.вопрос по серверной стороне, необходимо знать режим инициализации ServerSocket (thread-blocking/non-blocking), программное окружение созданного серверного объекта класса TServerSocket и конкретноею место в коде, где происходит обращение к методам/св-вам объекта класса TClientServerWinSocket, установившего соединение с "оборвавшимся" клиентом

Приводи код - разберем его


ChernoVVV   (2002-07-05 11:53:00) [4]

Почему же тогда на стороне сервера аналогичный GetRemoteAddress()не вызывает исключения ?


Digitman   (2002-07-05 10:43:00) [5]

Нет, это не чистый эксперимент.

Как минимум потому, что в контексте метода GetRemoteAddress() вызывается WinsockAPI-ф-ция :

CheckSocketResult(getpeername(FSocket, SockAddrIn, Size), "getpeername");


ChernoVVV   (2002-07-05 08:47:00) [6]

Клиент периодически делаю проверку [9сек] на (Active=true)and(ClientSocket.Socket.Connected)and(ClientSocket.Socket.RemoteAddress<>"")- это чистый эксперимент? Если на серверной части я буду проверять тоже самое для ServerSocket всегда будет true вне зависимости от подключения.


Digitman   (2002-07-05 08:06:00) [7]

Проведи заведомо "чистый" эксперимент : пусть твой ClientSocket выполнит успешный коннект к серверу и с этого момента "молчит", не выполняя никаких более методов (выполнение которых вполне может привести к OnError() при той же диагностике с последующим OnDisconnect). А вот теперь - "выдерни шнурок" из машины, где находится сервер...


ChernoVVV   (2002-07-04 18:55:00) [8]

Аргумент " OnError -> OnDisconnect" срабатывает в 99.99% случаях, во всяком случае у меня, может это как раз глюк :)


Digitman   (2002-07-04 18:26:00) [9]

>ChernoVVV

С чего ты взял, про ClientSocket ? Чем он принципиально отличается с т.з. единого используемого протокола от ServerSocket ?

Приведи, пожалуйста, аргументы в пользу такого утверждения.


ChernoVVV   (2002-07-04 18:18:00) [10]

Тогда почему факт обрыва связи отслеживает ClientSocket, ServerSocketмолчит ?


Digitman   (2002-07-04 17:53:00) [11]

Это - нормальная работа. Но не ServerSocket, а самого протокола TCP/IP.
Разрыв TCP/IP-соединения - понятие логическое, не физическо и в общем случае представляет собой факт получения приемником (и, как правило, отправки передатчиком) TCP-пакета с флагом-признаком RST (reset, сброс). Если "выдернут сетевой шнурок" хотя бы на одной из сторон, ни о каком логическом взаимодействии между удаленными партнерами не может быть и речи.


Наверх

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