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

Вниз

Проблема при дисконнекте   Найти похожие ветки 

 
VID   (2002-08-05 13:48) [0]

в общих чертах проблема в том что при событии onclientdisconnect я делаю след:
1. Отправляю всем клиентам, подключённым к серверу , к примеру S1(где, S1 - string)
2. Сразу же отправляю снова всем пользователям S2 - тоже String;

Приблизительно код выглядит так:
Procedure Server.OnClientDisconnect(..Socket:T...);
begin
SendPacketToAllClients(S1);
SendPacketToAllClient(S2);
end;

А вот и процедура SendPacket...

Procedure SendPacketToAllClients(Packet:String);
Var I:Integer;
begin
FOR I:=0 To Server.Socket.ActiveConnections - 1 do
Server.Socket.Connections [i].SendText(Packet);
end;

так вот при выполнении кода события onClientDisconnect , сервер виснет.
Причём, если прокомментировать одну из строк
(либо SendPacketToAllClients(S1), либо SendPacketToAllClient(S2)) то проблемы нет, сервак не виснет.


 
Digitman   (2002-08-05 14:04) [1]

Это - фрагмент хэлпа для события TServerWinSocket.OnClientDisconnect():

Occurs when one of the connections to a client socket is closed (!!!!!!!!!!!!!!!).


 
VID   (2002-08-05 14:17) [2]

дело в том, что в момент наступления OnClientDisconnect, Socket клиента ещё не закрыт... вот.
Но даже если переделать процедуру SendPacketToAllClients:
Procedure SendPacketToAllClients(Packet:String);
Var I:Integer;
begin
FOR I:=0 To Server.Socket.ActiveConnections - 1 do
IF SERVER.SOCKET.CONNECTIONS[i].CONNECTED THEN

Server.Socket.Connections [i].SendText(Packet);
end;

то всё равно проблема остаётся.

Да кстати, забыл сказать: если дисконнект происходит со стороны сервера (т.е. если сервер отключает клиента), то указанная проблема не возникает, даже если ни ода строка (в процедуре onClientDisconnect) не откомментирована. А вот если дисконнект со стороны клиента, то проблема есть


 
Digitman   (2002-08-05 14:37) [3]

И как же, позволь полюбопытствовать, ты что-то сможешь отослать клиенту по транспортному каналу, которого уже не существует ? Ведь в случае дисконнекта по инициативе клиента событие OnClientDisconnect() фиксирует именно факт уже произошедшего разрыва транспортного канала ! И в хэлпе об этом четко сказано - IS CLOSED.

разумеется, если дисконнект происходит по инициативе сервера, таким способом тебе еще что-то удастся (при асинхронном режиме) передать клиенту перед дисконнектом, но - не иначе !


 
VID   (2002-08-05 14:44) [4]

ну я так и знал.. спасибо :) кстати, server.servertype = nonblocking.
НУ тогда контрвопрос: а как же тогда быть ? Ведь мне надо после отключения клиента (неважно по чьей инициативе), послать ВСЕМ ОСТАВШИМСЯ сообщение типа "ушёл клиент "+Socket.RemoteAddress...
где же это сделать, что бы работало ?


 
Digitman   (2002-08-05 14:48) [5]

самый простой вариант :

если режим stThreadBlocking, попробуй просто заключить потенциально опасный send-метод в блок try..except


 
VID   (2002-08-05 14:57) [6]

нет нет... только не stThreadBlocking ... я использую stNonBlocking, и кстати, вот тебе вопрос:

№1 Почему же если откомментировать одну из строчек кода, приведённого в Server.OnClientDisconnect, то сервак не виснет, даже если дисконект был вызван со стороны клиента. Думается, что сервак просто "успевает" выполнить одну оставшуюся строчку кода, а если будет вторая то виснет.
И тут вопрос №2: Почему сервак вообще виснет? Зависание имеет след вид:
при событи onClientDisconnect у меня также есть ещё одна строчка (первее всех, но я её не указал, т.к. она не важна):
AddLog("Client "+Socket.RemoteAddress+" is disconnected");

Процедура AddLog:
Procedure Tform1.AddLog(Log:String);
begin
LogMemo.Lines.Add(Log);
end;

так вот зависание выглядит так:
сервер всё время добавляет лог :
Client 127.0.0.1 is disconnected
ВСЁ ВРЕМЯ. и не реагирует ни на что. Потом проихсодит переполнение стека и сервер выгружается из ОЗУ (Windows 2000).

И в продолжение темы:
№3 Как реализовать отправку всем оставшимся клиентам текстового сообщения, если Server.ServerType = stNonBlocking ?

Ps: прошу не задумываться над моим высказыванием "только не stThreadBlocking"... просто прими как факт ;)


 
Digitman   (2002-08-05 15:22) [7]

А как у тебя с обработкой события OnClientError () ? Игнорируешь ее ?


 
VID   (2002-08-05 15:52) [8]

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


 
Digitman   (2002-08-05 15:56) [9]

1. Сбросить ErrorCode в 0.
2. Выполнить Socket.Close


 
VID   (2002-08-05 17:03) [10]

ВОПРОС ЗАКРЫТ. Большое спасибо, Digitman.



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

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

Наверх





Память: 0.47 MB
Время: 0.007 c
1-21131
Oleon
2002-09-24 15:56
2002.10.07
Привет! Где можно выставить DEFAULT_CHARSET, чтобы кирилица была.


1-21073
123456789
2002-09-24 23:33
2002.10.07
Как правильно сворачивать программу в TrayBar?


3-20872
Sergey_Rom
2002-09-16 00:23
2002.10.07
Delphi5 dbf > Delphi5


14-21267
michael_b
2002-09-08 22:13
2002.10.07
Кто-нибудь видел пиратский Delphi7 Studio Architect


14-21255
Лана Розанова
2002-09-13 09:58
2002.10.07
Ребята, помогите.





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский