ServerSocket проверява за физически прекъсване на мрежата

Някой може ли да попадне на периодична проверка на клиентската връзка за наличност. Стресова ситуация - захранващият кабел е изваден иSocket.Connectedвръщаtrue. Това е проблем или нормална работа на ServerSocket.

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

Това е нормална работа. Но не ServerSocket, а самият TCP / IP протокол. Прекъсването на TCP/IP връзката е логическа концепция, а не физическа, и в общия случай представлява факта, че приемникът получава (и, като правило, изпраща от предавателя) TCP пакет с RST флаг (нулиране, нулиране). Ако „захранващият кабел е изваден“ поне от едната страна, не може да се говори за някакво логично взаимодействие между отдалечени партньори.

ChernoVVV ( 2002-07-04 18:18 ) [2]

Тогава защоClientSocketследи прекъснатата връзка, аServerSocketмълчи?

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

От това, което взе, за ClientSocket? С какво принципно се различава от т.нар. единичен протокол, използван от ServerSocket?

Моля да посочите аргументи в полза на подобно твърдение.

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

Аргументът "OnError -> OnDisconnect" работи в 99,99% от случаите, поне за мен, може би е просто проблем :)

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

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

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

Клиентът периодично проверява [9sec] за(Active=true)и(ClientSocket.Socket.Connected)и(ClientSocket.Socket.RemoteAddress<>"")- това чист експеримент ли е? Ако от страната на сървъра проверя същото за ServerSocket, винаги ще е вярно, независимо от връзката.

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

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

Най-малкото защото в контекста на метода GetRemoteAddress() се извиква функцията WinsockAPI:

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

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

Защо тогава от страната на сървъра подобенGetRemoteAddress()не хвърля изключение?

Digitman ( 2002-07-05 12:05 ) [9]

Аха! Хванахте ли изключението?) Всъщност това е отговорът на вашия въпрос от страна на клиента: клиентът е "мълчалив" - той няма да получи никакви известия, че "дантелата" на сървъра е "откъсната".

Но за да отговорите на аналогичен въпрос от страна на сървъра, трябва да знаете режима на инициализация на ServerSocket (блокиране на нишки / неблокиране), програмната среда на създадения сървърен обект на класа TServerSocket и конкретното място в кода, където се извикват методите / свойствата на обекта на класа TClientServerWinSocket, който е установил връзка с "счупения" клиент

Донесете кода - ние ще го анализираме

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

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

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

1. Е, къде е вашият манипулатор OnClientError()? Как ще прихванете изключителни ситуации при достъп до вече несъществуващ физически транспортен канал с клиент?

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

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

Има ли съмнения по този въпрос? Можете да проверите цялата тази логика (и трябваше да го направите отдавна!) в модула scktcomp.pas.

Добре ? По-нататък? Или ви убедих в неправилността на вашата версия за проверка на активността на връзката?