Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
IdTcpServer无法在CentOS+;下的context.connection.disconnect()之后释放其上下文线程;拉撒路_Centos_Lazarus_Indy10 - Fatal编程技术网

IdTcpServer无法在CentOS+;下的context.connection.disconnect()之后释放其上下文线程;拉撒路

IdTcpServer无法在CentOS+;下的context.connection.disconnect()之后释放其上下文线程;拉撒路,centos,lazarus,indy10,Centos,Lazarus,Indy10,在单击BTDISCON按钮后,Memo1的结果仍然是“connct:1”,尽管我等待了几分钟 但是在windows xp下,它可以正常工作,如何让idtcpserver删除无效的上下文线程 这是我的密码: 客户端(Windows7+DelphiXE2+Indy10.5.8): 服务器端(Vmware+CentOS+Lararus1.0.12+Indy10.5.8) 服务器代码存在两个问题,无法正常关闭: 您的OnExecute代码正在捕获并丢弃所有异常,并且不允许TIdTCPServer处理任何

在单击BTDISCON按钮后,Memo1的结果仍然是“connct:1”,尽管我等待了几分钟

但是在windows xp下,它可以正常工作,如何让idtcpserver删除无效的上下文线程

这是我的密码:

客户端(Windows7+DelphiXE2+Indy10.5.8):

服务器端(Vmware+CentOS+Lararus1.0.12+Indy10.5.8)


服务器代码存在两个问题,无法正常关闭:

  • 您的
    OnExecute
    代码正在捕获并丢弃所有异常,并且不允许
    TIdTCPServer
    处理任何异常。停用
    TIdTCPServer
    时,它会关闭所有活动套接字,从而导致当前/后续套接字操作失败并引发异常。通过丢弃异常,
    TIdTCPServer
    不知道连接已经关闭,并且愉快地继续调用
    OnExecute
    事件。如果必须捕获异常(例如记录异常),则需要在处理完异常后重新引发任何Indy特定的异常,以便
    TIdTCPServer
    可以处理它们

  • 您正在以线程不安全的方式访问
    TMemo
    ,这可能(除其他外)导致死锁

  • 请尝试以下方法:

    uses
      ..., IdSync;
    
    type
      TMemoNotify = class(TIdNotify)
      protected
        FMsg: String;
        procedure DoNotify; override;
      public
        class procedure AddToMemo(const AMsg: string);
      end;
    
    procedure TMemoNotify.DoNotify;
    begin
      Form1.Memo1.Lines.Add(FMsg);
    end;
    
    class procedure TMemoNotify.AddToMemo(const AMsg: string);
    begin
      with Create do
      begin
        FMsg := AMsg;
        Notify;
      end;
    end;
    

    除了重新引发Indy异常之外,您还可以完全取消
    OnExecute
    事件中的异常处理,并使用
    TIdTCPServer.OnException
    事件:

    procedure TForm1.TcpServerExecute(AContext: TIdContext);
    var
      b: Byte;
    begin
      b := AContext.Connection.IOHandler.ReadByte;
      ...
    end;
    
    procedure TForm1.TcpServerException(AContext: TIdContext; AException: Exception);
    begin
      TMemoNotify.AddToMemo('Error:'+AException.Message);
    end;
    

    OT:移动行
    lst:=TcpServer.Contexts.LockList()
    lst:=TcpServer.Contexts.LockList()之前尝试
    关键字。在调用
    Disconnect()
    之后不要调用
    DiscardAll()
    ,因为套接字现在已关闭,因此无法读取更多数据。如果您只想清除
    InputBuffer
    ,那么直接执行:
    itm.Connection.IOHandler.InputBuffer.clear
    
    uses
      ..., IdSync;
    
    type
      TMemoNotify = class(TIdNotify)
      protected
        FMsg: String;
        procedure DoNotify; override;
      public
        class procedure AddToMemo(const AMsg: string);
      end;
    
    procedure TMemoNotify.DoNotify;
    begin
      Form1.Memo1.Lines.Add(FMsg);
    end;
    
    class procedure TMemoNotify.AddToMemo(const AMsg: string);
    begin
      with Create do
      begin
        FMsg := AMsg;
        Notify;
      end;
    end;
    
    uses
      ..., EIdException;
    
    procedure TForm1.FormShow(Sender: TObject);
    var
      Bind: TIdSocketHandle;
    begin
      TCPServer.Bindings.Clear;
      Bind := TCPServer.Bindings.Add;
      Bind.IPVersion := Id_IPv4;
      Bind.Port := 10000;
      TcpServer.OnExecute := TcpServerExecute;
      TcpServer.Active := True;
      Timer1.Interval := 5000;
      Timer1.Enabled := True;
    end;
    
    procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
    begin
      Timer1.Enabled := False;
      TcpServer.Active := False;
    end;
    
    procedure TForm1.TcpServerExecute(AContext: TIdContext);
    var
      b: Byte;
    begin
      try
        b := AContext.Connection.IOHandler.ReadByte;
      except
        on E: Exception do
        begin
          TMemoNotify.AddToMemo('Error:'+E.Message);
          if E is EIdException then raise;
        end;
      end;
    end;
    
    procedure TForm1.Timer1Timer(Sender: TObject);
    var
      lst: TList;
    begin
      lst := TcpServer.Contexts.LockList;
      try
        Memo1.Lines.Add('ConnCnt:'+IntToStr(lst.Count));
      finally
        TcpServer.Contexts.UnlockList;
      end;
    end;
    
    procedure TForm1.btDisconnClick(Sender: TObject);
    var
      i: Integer;
      lst: TList;
    begin
      lst := TcpServer.Contexts.LockList;
      try
        for i := 0 to lst.Count-1 do
        begin
          try
            TIdContext(lst.Items[i]).Connection.Disconnect;
           except
           end;
        end;
      finally
        TcpServer.Contexts.UnlockList;
      end;
    end;
    
    procedure TForm1.TcpServerExecute(AContext: TIdContext);
    var
      b: Byte;
    begin
      b := AContext.Connection.IOHandler.ReadByte;
      ...
    end;
    
    procedure TForm1.TcpServerException(AContext: TIdContext; AException: Exception);
    begin
      TMemoNotify.AddToMemo('Error:'+AException.Message);
    end;