最近在用indy 10.5.5版本的 IdTcpServer 及 IdTcpClient做开发,整个过程很不顺利,官方没demo,网上的一些demo又过于简单。
 
困惑1:
客户端每次和服务端通讯完成后立即断开IdTCPClient.Disconnect这样没问题,但如果服务端主动断开客户端AContext.Connection.Disconnect,运行几次就会出问题。不知道为什么? 客户端和服务端是不是每次完成通讯后都必须Disconnect?那为什么服务端主动Disconnect会出问题?困惑2:
客户端可能会并行几个任务,所以我是每次需要通讯时动态创建一个IdTCPClient,用完后Free。这样做好吗?困惑3:
关于通讯的问题,我现在的做法是在一个过程中完成多次通讯,不知这样做是否正确?请看下面的代码。。代码及流程图如下:客户端      服务端 
   |------> |
   |        |
   | <------|
   |        |
   |------> |
   |        |
   | <------|
客户端代码:procedure TForm1.Button1Click();
var
  aClient: TIdTCPClient;
  str: string;
begin
  //创建及连接代码在此省略。  aClient.IOHandler.WriteLn('1');
  str := aClient.IOHandler.ReadLn;
  //在此做一些处理......  aClient.IOHandler.WriteLn('2');
  str := aClient.IOHandler.ReadLn;
  //在此做一些处理......  //断开
end;
服务端代码:procedure TForm1.ServerExecute(AContext: TIdContext);
var
  str: string;
begin
  str := AContext.Connection.IOHandler.ReadLn;
  //在此做一些处理......
  AContext.Connection.IOHandler.WriteLn('1');  str := AContext.Connection.IOHandler.ReadLn;
  //在此做一些处理......
  AContext.Connection.IOHandler.WriteLn('2');
  //在此并不做断开,否则运行一段时间就会出现一些死连接,不知为什么。。?
end;

解决方案 »

  1.   

    我也碰到这样的问题。
    对indy玩的不多。原本只习惯于直接 socket api。
    在连接前,先断开连接。这样可能会少几次报错。
      

  2.   

    參考之:
    http://www.pudn.com/downloads122/sourcecode/p2p/detail519196.html
      

  3.   

      TClient   = record  // Object holding data of client (see events)
                    DNS         : String[20];            { Hostname }
                    Connected,                           { Time of connect }
                    LastAction  : TDateTime;             { Time of last transaction }
                    Thread      : Pointer;               { Pointer to thread }
                  end;  PClient   = ^TClient;procedure TFormMain.TCPServerConnect(AThread: TIdPeerThread);
    var
      NewClient: PClient;
    begin
      GetMem(NewClient, SizeOf(TClient));  NewClient.DNS         := AThread.Connection.LocalName;
      NewClient.Connected   := Now;
      NewClient.LastAction  := NewClient.Connected;
      NewClient.Thread      := AThread;  AThread.Data:=TObject(NewClient);  try
        Clients.LockList.Add(NewClient);
      finally
        Clients.UnlockList;
      end;
    end;procedure TFormMain.TCPServerDisconnect(AThread: TIdPeerThread);
    var
      ActClient: PClient;
    begin
      ActClient := PClient(AThread.Data);
      try
        Clients.LockList.Remove(ActClient);
      finally
        Clients.UnlockList;
      end;
      FreeMem(ActClient);
      AThread.Data := nil;
    end;procedure TFormMain.TCPServerExecute(AThread: TIdPeerThread);
    var
      ActClient, RecClient: PClient;
      RecThread: TIdPeerThread;
    begin
      if not AThread.Terminated and AThread.Connection.Connected then begin
        with Clients.LockList do begin
          try
            for i := 0 to Count-1 do begin// iterate through client-list
              RecClient := Items[i];           // get client-object
              RecThread := RecClient.Thread;     // get client-thread out of it
              iLen := RecThread.Connection.ReadFromStack(false, 20, false);
                     end;
              do something...
          finally
            Clients.UnlockList;
          end;
        end;
      end;
    end;
      

  4.   

    procedure TFormMain.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      TcpServer.Active := False;
      Clients.Free;
      Release;
    end;
      

  5.   

    9 10楼用的是INDY9.答不对题啊