idtcpserver.active := false 程序就僵死了。

解决方案 »

  1.   

    你这么问问题,神仙也没法回答啊,谁知道你的程序怎么写的啊,你得描述清楚了,别人才能回答。
    idtcpserver.active := false  
    就单独这么一句话,如果没有其他代码,程序是不可能崩溃的。
      

  2.   

    恩,我把我的代码贴出来。代码如下:
    unit MainForm;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ComCtrls, ExtCtrls, AdvPanel, AdvGlowButton, Menus, ImgList,global,
      AdvOfficePager, IdBaseComponent, IdComponent,IdUDPBase, IdUDPServer, IdContext,
      IdCustomTCPServer, IdTCPServer,IdGlobal,IdSocketHandle,Grids, AdvObj, BaseGrid,
      AdvGrid, StdCtrls, pngimage, jpeg,IdSchedulerOfThreadPool, IdScheduler,
      IdSchedulerOfThread, IdAntiFreezeBase, IdAntiFreeze;type
      Tf_mainForm = class(TForm)
        UDPServer: TIdUDPServer;
        Image1: TImage;
        Image2: TImage;
        PageControl1: TPageControl;
        TabSheet1: TTabSheet;
        TabSheet2: TTabSheet;
        TabSheet3: TTabSheet;
        softListGrid: TAdvStringGrid;
        Splitter1: TSplitter;
        SoftDetailGrid: TAdvStringGrid;
        ImageList: TImageList;
        IdSchedulerOfThreadPool1: TIdSchedulerOfThreadPool;
        IdAntiFreeze1: TIdAntiFreeze;
        TCPServer: TIdTCPServer;
        procedure FormCreate(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure btExitClick(Sender: TObject);
        procedure btnSetClick(Sender: TObject);
        procedure FormShow(Sender: TObject);
        procedure TCPServerExecute(AContext: TIdContext);
        procedure UDPServerUDPRead(AThread: TIdUDPListenerThread;
          AData: TIdBytes; ABinding: TIdSocketHandle);
        procedure TCPServerDisconnect(AContext: TIdContext);
        procedure TCPServerConnect(AContext: TIdContext);
        function AddRequest(RequestRec: TRequestRec;ClientIp: string;Context: TidContext):TSoftWareRec;
    end
    var
      f_mainForm: Tf_mainForm;
      QueueClientList: TstringList;
      CS: TRTLCriticalSection;
    implementation
    procedure Tf_mainForm.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      DeletecriticalSection(CS);
      tcpserver.StopListening;
      //tcpserver.IOHandler.Shutdown;
      //IdSchedulerOfThreadPool1.TerminateAllYarns;
      //
      //
     end;
    procedure Tf_mainForm.FormCreate(Sender: TObject);
    begin
      InitializeCriticalSection(CS);
    end;
     procedure Tf_mainForm.FormShow(Sender: TObject);
    begin
      if not UdpUpdateStatus or not tcpUpdatestatus then
        infoMessage('服务器端口已被占用,请重新设置端口');
    end;
    function Tf_mainForm.UdpUpdateStatus: boolean;
    begin
      try
        UDPServer.OnUDPRead := UDPServerUDPRead;
        UDPServer.DefaultPort := strtoint(AppUdpPort);
        UDPServer.Active := true;
        result := true;
      except
        result := false;
      end;
    end;
    procedure Tf_mainForm.TCPServerConnect(AContext: TIdContext);
    begin
      showmessage(AContext.Connection.Socket.Binding.PeerIP);
    end;procedure Tf_mainForm.TCPServerDisconnect(AContext: TIdContext);
    begin
      showmessage('disConnect');
    end;
    procedure Tf_mainForm.TCPServerExecute(AContext: TIdContext);
    var
      flag: string[1];
      tmpBuffer: tIdbytes;
      RequestRec: TRequestRec;
      CIP,FSpecialityCaption,tmpstr,IP: string;
      ClientInfo: TClientInfo;
      index,softid,maxusers,linkedusers,linkingusers,i,count: integer;
      SoftWareRec: TSoftWareRec;
      softids: string;
      stream,serverRec: Tmemorystream;
    begin
       AContext.Connection.Socket.CheckForDataOnSource(250);
       if not AContext.Connection.Socket.InputBufferIsEmpty then
       begin
         stream := Tmemorystream.Create;
         serverRec := Tmemorystream.Create;
         AContext.Connection.Socket.ReadStream(stream);
         stream.Position := 0;
         if stream.Size>0 then
         begin
           stream.Read(flag,sizeof(flag));
           EnterCriticalSection(CS);
           IP :=AContext.Connection.Socket.Binding.PeerIP;
           CIP := AContext.Connection.Socket.Binding.PeerIP ;
           stream.Position := 0;
           while stream.Position<stream.Size do
           begin
             if Flag = '.' then
             begin
               stream.Read(RequestRec,sizeof(TRequestRec));
               SoftWareRec := AddRequest(RequestRec,CIP,AContext);
               serverRec.WriteBuffer(SoftWareRec,sizeof(SoftWareRec));
             end;
           end;
           index := clientList.IndexOf(CIP);
           if index>-1 then
             TClientInfo(ClientList.Objects[index]).ContextList.AddObject(CIP,AContext);
           serverRec.Position := 0;
           AContext.Connection.Socket.Write(serverRec,serverRec.Size,true);
         end;
         FreeAndnil(stream);
         FreeAndNil(serverRec);
         LeaveCriticalSection(CS);
       end;
    end;
    function Tf_mainForm.tcpUpdatestatus: boolean;
    var
      port: integer;
    begin
      result := false;
      port := strtoint(AppUdpPort)+1;
      while true do
      begin
        try
          TCPServer.DefaultPort := port;
          TCPServer.Active := true;
          result := true;
          break;
        except
          inc(port,1);
        end;
      end;
      AppTcpPort := inttostr(port);
      TCPServer.TerminateWaitTime := 0;
    end;
    就这样,主窗体一关闭,程序就僵死了。
      

  3.   

    你代码没贴全吧,
    TCPServerExecute你这个函数里面写的有点危险
    如果在EnterCriticalSection(CS);和FreeAndnil(stream);
    两句话中间有异常退出的话,会导致你的临界区无法退出,这样你在关闭窗口的时候,DeletecriticalSection(CS);就会崩溃。
    你用try finally括起来处理安全一些。
    tcpserver.StopListening;
    这个也有可能导致崩溃,你检查一下你的代码,关闭钱,把能释放的内存都释放,能断开的链接都断开。
    多调试几次,应该很容易定位到错误。
      

  4.   

    只能tcpserver存在连接,在主窗体关闭之后,程序就僵死了。也就是不能完全退出
      

  5.   

    你把TCPServerExecute的代码注释掉,运行看看是否还报错,如果还报错,你注释掉一些可疑的代码,直到找到那个地方位置。如果是以为内tcpserver存在连接导致的,你就保存一下连接上来的IP,在关闭程序之前断开这些连接。就行了
      

  6.   

    AContext.Connection.Socket.ReadStream(stream);
    你读多大的东西?