Конференция "Сети" » Как избавиться от сообщений ClosedGracefully ? [D7, WinXP]
 
  • Winni (30.11.10 23:52) [0]
    Посоветуйте, пожалуйста, как проще всего отключиться от
    TCP-сервера (IdTCPServer1: TIdTCPServer;) не получая сообщений ClosedGracefully ? Мучаюсь уже 3-ий день, пробовал разные варианты, но сообщения эти все же появляются, может быть немного чаще или реже. У меня к серверу подключены 5 клиентов TIdTCPClient;
    К моменту отключения они не обмениваются сообщениями.
    Отключение произвожу со стороны клиента, при этом серверу
    ничего не сообщаю, надеясь, что он отключит соответствующие
    веточки. При этом клиент выполняет:

    procedure TFormMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    var comma,repa: string;
    begin
     if MessageDlg('Вы уверены, что хотите выйти из игры?'+#13#10+
     '(не менее двух раз)', mtConfirmation,[mbYes, mbNo], 0) = mrNo then
        CanClose := False else
        begin
          TM1.Enabled:= false;
          if Client.Connected then
            begin
              Client.DisConnect;
              CanClose := False;
            end
                else
            CanClose:= True;
        end;
    end;

    При 1-й попытке закрыть форму отключается таймер
    (который посылал команды на сервер) и отключается
    IdTCPClient при 2-й попытке - закрывается форма.
    сообщения ClosedGracefully появляются чаще при 2-й
    попытке, но бывают и при 1-й.
    Написано, что это сообщение возникает, если соединение
    закрыто с другой стороны, а клиент пытается что-то прочесть или
    записать.

    Идея с 2-я попытками - отладочная, попытка что-то понять,
    но пока ни просвета.
  • Медвежонок Пятачок © (01.12.10 00:57) [1]
    unit idStak;

    procedure TIdStack.RaiseSocketError(const AErr: integer);
    begin
     (*
       RRRRR    EEEEEE   AAAA   DDDDD         MM     MM  EEEEEE    !!  !!  !!
       RR  RR   EE      AA  AA  DD  DD        MMMM MMMM  EE        !!  !!  !!
       RRRRR    EEEE    AAAAAA  DD   DD       MM MMM MM  EEEE      !!  !!  !!
       RR  RR   EE      AA  AA  DD  DD        MM     MM  EE
       RR   RR  EEEEEE  AA  AA  DDDDD         MM     MM  EEEEEE    ..  ..  ..

       Please read the note in the next comment.



    ну так плиз, рид зе ноте ин зе некст коммент.
  • Winni (01.12.10 07:27) [2]
    Спасибо, попробую найти и почитать FAQ, однако боюсь, что утону там :-((
  • Winni (01.12.10 07:33) [3]
    Однако, страничка
    http://www.nevrona.com/Indy/FAQ.html
    не открывается, нет ее уже :-((
  • Медвежонок Пятачок © (01.12.10 09:04) [4]
    я тоже по той ссылке не ходил.
    когда получил свой первый грэйсфул клозет.
    мне хватило коментария в самом модуле начало которого приведено выше.
  • Anatoly Podgoretsky © (01.12.10 09:32) [5]
    > Winni  (30.11.2010 23:52:00)  [0]

    Никак, можно только не показывать. Это нормальный разрыв связи, нету потока
    данных/команд и другая сторона просто разорвет соединение и это не ошибка.
  • Winni (01.12.10 12:36) [6]
    Спасибо.

    Да, я тоже читал, что это нормально, но все-таки наверное, не совсем,
    ибо нажимать до 50 раз на ОК этого окошка все же не нормально.
    А как можно не показывать ? Я пытался сообразить, в каком месте поставить
    try , но не сообразил, ибо нет вроде бы чтения-записи в это время.
    Видимо, придется один из клиентов запустить в Делфи, в режиме отладки.

    Забавно, что при числе клиентов < 4 это не возникает и при отключении первых двух тоже.
    Не поленился вклинить между клиентом и сервером SocketSpy и увидел, что сообщения эти не сопровождаются передачей чего либо по сети. Но вот что непонятно: вроде бы клиент не передает и не читает что-либо из соединения. То есть нет причины ему возмущаться.
    Почитаю внимательнее рекомендуемый комментарий, может что дойдет.
  • Медвежонок Пятачок © (01.12.10 13:06) [7]
    ибо нажимать до 50 раз на ОК

    Ты выбирай.
    Либо прокачивай пальцы, кликая на Ок, либо прокачивай знания, читая основы языка. Обработку там всяких исключений и прочие конструкции.
  • Anatoly Podgoretsky © (01.12.10 13:44) [8]
    Читай FAQ, смотри примеры.
  • Winni (01.12.10 17:56) [9]
    Нашел, однако.
    Действия readln,writeln  в соединение, запущенные
    таймером, продолжались, естественно какое то время после остановки
    таймера. А у меня (см выше ) сразу после остановки таймера
    стоит disconnect (без разрыва во времени).
    И кроме того, эти readln,writeln не были заключены
    в try.. except но это проглядел, каюсь. А то бы увидел - где
    это происходит.

    Теперь добавил 2-й таймер. Получается так:

    procedure TFormMain.N3Click(Sender: TObject);
    begin
     if MessageDlg('Вы уверены, что хотите выйти из игры?',
        mtConfirmation,[mbYes, mbNo], 0) = mrYes then
        begin
          TM1.Enabled:= false;
          TM2.Enabled:= true;
        end;
    end;

    procedure TFormMain.TM2Timer(Sender: TObject);
    begin
      TM2.Enabled:= false;
      if Client.Connected then
        begin
          try
          Client.DisConnect;
          except
          on E: EIdException do
            begin
               showmessage('MyErrorDisConnect');
            end;
          end;
        end;
      if not Client.Connected then
      Application.Terminate;
    end;

    хотя обычно DisConnect не заключают в блок try и это
    можно выкинуть и расслабиться. Спасибо за поддержку.
    Тяжелая артиллерия не понадобилась :-))
  • Winni (02.12.10 13:30) [10]
    Рано обрадовался.
    После переделок программы проблема вернулась.
    Похоже, что нужно это исключнение
    вообще игнорировать, т е

    try
      ....
     except
         on E: EIdConnClosedGracefully do
            begin
                // nothing
            end;
         on E: EIdException do
            begin
                showmessage('Ошибка: таймер, №1'+ E.Message);
            end;
     end;

    Этого тсключения теперь не видно,
    но часто виснет этот клиент. Все равно что-то не то и нужно
    искать.
  • Anatoly Podgoretsky © (02.12.10 17:02) [11]
    try
     ....
    except
        on E: EIdException do
           begin
               showmessage('Ошибка: таймер, №1'+ E.Message);
           end;
    end;

  • Winni (02.12.10 22:44) [12]
    Спасибо, попробую, если сохранил эту версию (сейчас у меня уже 8-я версия).
    То есть Вы хотите сказать, что сработают оба ON, а я думал, что как CASE, т е первая и сразу на выход.  
    Но мне больше понравилось отключение со стороны сервера, т е клиент посылает 'QUIT', который сервер, прочитав строку,  распознает как команду и закрывает эту веточку методом Disconnect. Хотел приблизится к описанному в Вашем переводе способу, когда сервер в ответ на эту команду отвечает клиенту что-нибудь, например 'bye' и сразу после этого Disconnect,  а клиент, получив это 'bye' закрывает себя, т е Client.DisConnect . Но почему то не вышло и забросил я такой вариант. Вроде пока с этим проблем нет. Сейчас так:

    procedure TFormMain.TM2Timer(Sender: TObject);
    begin
      TM2.Enabled:= false;

     if  Client.Connected then
          try
            Client.WriteLn('QUIT');
          except
            on E: EIdConnClosedGracefully do
            begin
                // nothing
            end;
            on E: EIdException do
            begin
                showmessage('Ошибка: N3Click'+ E.Message);
            end;
          end;

    Application.Terminate;
    end;

    Хорошо бы иметь подборку примеров с тематическим оглавлением, наверное где-то он есть.
 
Конференция "Сети" » Как избавиться от сообщений ClosedGracefully ? [D7, WinXP]
Есть новые Нет новых   [134436   +25][b:0][p:0.001]