本帖最后由 darlingpeng 于 2012-05-30 19:03:21 编辑

解决方案 »

  1.   

    为什么不用UDP协议 在OnDisconnect 是已断开后进行的一些处理 AThread.Connection.Disconnect 
     DisconnectSocket 
    断不开 ?这就不清楚了
      

  2.   

    谢谢 !GPRS本身使用的是这个协议 。
      

  3.   

    我发现,是因为断开数据时出现Connection Closed Gracefully异常。如下面最简单的程序:
    ----------------------------------------
    unit Unit2;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, IdAntiFreezeBase, IdAntiFreeze, IdThreadMgr, IdThreadMgrDefault,
      IdBaseComponent, IdComponent, IdTCPServer, IdSocketHandle;type  Tfrm_main = class(TForm)
        tcp_server: TIdTCPServer;
        IdThreadMgrDefault1: TIdThreadMgrDefault;
        IdAntiFreeze1: TIdAntiFreeze;
        procedure tcp_serverConnect(AThread: TIdPeerThread);
        procedure tcp_serverException(AThread: TIdPeerThread;
          AException: Exception);
        procedure tcp_serverExecute(AThread: TIdPeerThread);
        procedure FormShow(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure tcp_serverDisconnect(AThread: TIdPeerThread);
      private
        { Private declarations }
        procedure proc_set_server();
      public
        { Public declarations }
      end;var
      frm_main: Tfrm_main;implementation{$R *.dfm}procedure Tfrm_main.tcp_serverConnect(AThread: TIdPeerThread);
    begin
      AThread.FreeOnTerminate:=true;
    end;procedure Tfrm_main.tcp_serverException(AThread: TIdPeerThread;
      AException: Exception);
    begin
      AThread.Data:=nil;
       if AThread.Connection.Connected then
       AThread.Connection.DisconnectSocket;
       try
       AThread.Free;
       except
       end;
    end;procedure Tfrm_main.tcp_serverExecute(AThread: TIdPeerThread);
    begin
      with AThread.Connection do
      begin
        ReadfromStack();
      end;
    end;procedure Tfrm_main.proc_set_server();
    begin
      if tcp_server.Active then tcp_server.Active := false;
      tcp_server.DefaultPort := 10012;
      tcp_server.Active := true;
    end;procedure Tfrm_main.FormShow(Sender: TObject);
    begin
      proc_set_server();
    end;procedure Tfrm_main.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      tcp_server.Active:=false;
    end;procedure Tfrm_main.tcp_serverDisconnect(AThread: TIdPeerThread);
    begin
      ;
    end;end.
    也不触发OnDisconnect。只有在OnExecution中加try...except exit;end;时才会好。
    但为什么会出现这个异常?
      

  4.   

    procedure Tfrm_main.tcp_serverExecute(AThread: TIdPeerThread);
     begin 
      with AThread.Connection do  
      begin  
         ReadfromStack(); 
         write
         Disconnect;//这里断开  
      end; 
    end; 
      

  5.   

    谢谢mhhaifeng, 
      我发现,在连接后,OnExecution就会阻塞在ReadfromStack();,这样,当客户端一断开,就会出现Connection Closed Gracefully。这样也能理解,但怎么去掉这个异常?
      

  6.   

    不会阿,我也是使用 INDY 的 TCP SERVER 做 GPRS 的服务器端,没有你说的问题。很可能是你 GPRS 端没有写关闭连接的代码。我连接 GPRS 的蕊片是华为的 EM310 (GSM) 及 MC323 (CDMA2000),下面是我 GPRS 端断开连接的代码:EM310:/只有在TCP/UDP处于CONNECT OK的状态下才返回OK,否则返回ERROR
    AT+CIPCLOSE //关闭移动场景
    AT+CIPSHUTDOWN
    MC323://关闭所有连接
    AT^IPCLOSE=7
      

  7.   

    谢谢meegowei1 !!!!!!!!!!软件现在已经使用,但我发现,5天时间TCP没有关闭累积达到1700多,这会超过TCP的最大连接数,这时就会出现问题。
    所以,我想问大家,有什么好方法。现在情况是:
    GPRS连接,发送数据,20秒后自动断开连接。但发现,有时断不开。做硬件的同事也说,有时有问题。所以我这里就应该有所处理。请大家提供一些好的方法
    谢谢!!!
      

  8.   

    我现在想,在一天的某个时候, 如半夜0点,释放掉所有连接的TCP线程。
    但我试了几个方法都不成功。如何释放掉Threads中的所有线程链接?从而使IdTCPServer1.Threads.LockList.Count值为0
      

  9.   

    有人说用下面的方法:
    procedure Tfrm_main.proc_disconnect_all();
    var
      i: Integer;
      List: TList;
    begin
      with IdTCPServer1.Threads do
      begin
        List := LockList;
        try
          try
            for i := List.Count-1 downto 0 do
              TIdPeerThread(List[i]).Connection.Disconnect;
          except
          end;
        finally
          UnlockList;
        end;
      end;
    end;我试了一下,不行,并且退出时都会和死机一样。
    我用TCP调试助手,连接后,再断开,不论多少次,只要成对,退出时Threads.LockList.Copunt都是0,而我在服务器端主动Disconnect就不行。
    为什么?