INDY的TIDTCPSERVER在有客户端连接时关闭服务器程序时,总是报线程超时,该如何解决?
在CSDN里找了很长时间未果,请高手赐教

解决方案 »

  1.   

    楼上的不能再说这话了,危险另外,有客户端连接而关服务器程序的话,你必须在onclose里面把所有连接线程断开才关
      

  2.   

    将你的接收部分改成类似下面:
       try
         sCommand:=idTCPClient1.ReadLn();  
       except
         Exit;
       end;改了之后调试时(即用Delphi上的运行时)还会有错,直接执行编译的exe就不再提示出错了.
      

  3.   

    我也碰到这个问题,给你一段代码
    在TCPServer.Active := false前
    加一个函数
    procedure TfrmIndy.btnDisconnectAll;
    var
      List: TList;
      I: Integer;
    begin
      List := TCPServer.Threads.LockList;
      try
        for I := 0 to List.Count - 1 do
        begin
          try
            //if TCPServer.Checked then
            //begin
              //TIdPeerThread(List.Items[I]).Connection.WriteLn('#');
            //end;
            TIdPeerThread(List.Items[I]).Connection.Disconnect;
          except
            //on E: EIdNotConnected do
            //begin
            //  //Dont worry about this error
            //end;
            on E: Exception do
            begin
              form1.spSkinMemo1.Lines.Add('Exception (' +datetimetostr(Now) + ') [' + E.ClassName + ']: ' + E.Message);
              form1.spSkinMemo1.Lines.Add('The thread has been stopped');
              TIdPeerThread(List.Items[I]).Stop;
            end; //on
          end; //try
        end; //for
      finally
        TCPServer.Threads.UnlockList;
      end;
    end;在直接运行EXE时不会报错,但在程序运行时还是会保超时的错。
      

  4.   

    这个不太好调。。
    你要的话,我这有程序
    bloodsucker_1◎163.com
      

  5.   

    不好意思,我在上面写的代码我自己试了一下,还是会TIMEOUT,我到现在也没试出来怎么才能在有连接的情况下关闭TIDTCPSERVER控件.而且不出错.
    哪位高手指点一下
      

  6.   

    嗯,我目前只是通过TRY .. EXCEPT来屏蔽的。
      

  7.   

    procedure Tfrm_ServerMain.BitBtn2Click(Sender: TObject);       //强制关闭所有连接线程
    var
      i,j : integer;
    begin
      j := MyList.LockList.Count;
      MyList.UnlockList;
      if j > 0 then
      begin
        for i := 0 to j -1 do
        begin
          TIdPeerThread(MyList.LockList.Items[i]).Connection.Disconnect;
          MyList.UnlockList;
        end;
      end; 
    end;
      

  8.   

    我刚用indy组件的idftpserver写完一个ftp服务器,同样碰到线程结束超时的错误,我解决的方法如下:
    获得线程的id后如下操作线程:
     Athread.FreeOnterminated:=true(可以不要,因为indy在完成一个客户连接后,自动销毁线程)
     Athread.connection.disconnect;(调用此事件,实际上就是告诉客户,将结束这个线程,indy会自动销毁)
    try
     Athread.WaitFor
    except
    end;(不如此,程序会报“句柄无效”的错误,因为此时indy可能已经结束了线程)(如果你要终止很多用户,创建一个线程列表,然后循环,在循环中加入上述得处理方法,便一切ok,我就时这样处理得,欢迎使用我得实验品:E-Serv软件,发布在“上传下载的栏目里”,你也可以来信索取:[email protected] .你可以看:我的软件就可以在有客户端连接的时候强行终止客户的连接)//此时就可以终止服务器了
    idTcpServer.Active:=false(调试时当然有异常,保护起来,脱离调试环境,运行程序,一切ok)
    愿能帮得上你得忙◎!
      

  9.   

    tyxycylwxl(自由生活):我用的是TIdTCPServer组件,代码如下:


    VarTList:=Form1.IdTCPS.Threads.LockList;
            For Place:=0 To VarTList.Count Do Begin
              TIdPeerThread(VarTList).Connection.Disconnect;
              Try
              TIdPeerThread(VarTList).WaitFor;
              Except
              End;
            End;
            If Form1.IdTCPS.Active Then Form1.IdTCPS.Active:=False;



    却出这样的错误:Access violation at address BE66C38B. Read of address BE66C38B
      

  10.   

    VarTList:=Form1.IdTCPS.Threads.LockList;
            For Place:=0 To VarTList.Count Do Begin
              Try
              TIdPeerThread(VarTList.Items[Place]).FreeOnTerminate:=True;
              TIdPeerThread(VarTList.Items[Place]).Connection.Disconnect;
              TIdPeerThread(VarTList.Items[Place]).WaitFor;
              Except
                On WaitforError:Exception Do Begin
                  Form1.Memo1.Lines.Add(WaitForError.Message); 
                End;
              End;
            End;改成这样,窗体就没了反映。
    整个程序在cpu中也没有看到占多大的cpu时间。
      

  11.   

    最近我看到indy里面好象有个数据通道线程:TDatachannelthread,是不是应该先关闭所有数据通道,然后再断开连接?有可能从这方面考虑??!
      

  12.   

    我的程序已经完全改成了ics控件来代替indy控件,现在一切正常,唯一的一个特点,就是用leapftp,flashfxp上传或者下载时程序界面反应迟钝,可能涉及到数据发送创建线程的问题,正在焦头烂额!
    至于你说的错误:
    Access violation at address BE66C38B. Read of address BE66C38B
    有可能是访问了你的不存在的线程列表出现的错误:提供例子代码如下:procedure TfrmMain.StopServices();
    var e,h:integer;
        endthr:TIdPeerThread;
    begin
      e:=thrList.Count;
      if e>0 then begin
        for h:=0 to e-1 do begin
          endthr:=thrList.Items[h];
          endthr.FreeOnTerminate:=true;
          endthr.Connection.Disconnect;
          try
            endthr.WaitFor;
          except
          end;
        end;
      end;
    end;
      

  13.   

    实在还不能解决,你加我qq:15957198,我发份我的源码给你(TIdftpserv),虽然控件不同,但是我觉得原理相同
      

  14.   

    其实也不是indy的问题还是Socket本身的问题。indy还是很好的,在服务器端主动断开客户端连接时,一定要做的事情是要把buffer清空。