Форум: "Сети";
Текущий архив: 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