怎样利用多线程,在一个程序里,同时用使两个IdTcpclient进行收发信息,互不影响?

解决方案 »

  1.   

    CreateThread(nil,0,@send_msg,data,0,ThreadID);
      

  2.   

    创建两个线程,每个线程里动态创建IDTcpClinet控件,在线程里进行收发啊
      

  3.   

    我用了两个TTHREAD后,显视可以连接上,但就收不到信息,好像有一线程死掉了,,
    贴上代码,高手们帮忙指正一下错在哪里.
    program Client;{$APPTYPE CONSOLE}uses
      SysUtils,Windows,shellapi,Classes,IdTCPClient;
    {----------------二个线程类---------------------}
    type
    TClientThreadone = class(TThread)
                private
                protected
                procedure Execute; override;
                Public
                constructor Create;
                destructor Destroy; override;
    end;
    TClientThreadtwo = class(TThread)
     IdTCPClient :TidTcpClient;
                private
                protected
                procedure Execute; override;
                Public
                constructor Create;
                destructor Destroy; override;
    end;
    {----------------全局变量--------------------}
    var
      ClientThreadOne: TClientThreadone;
      ClientThreadtwo: TClientThreadtwo;
      IdTCPClient1 :TIdTCPClient;
    {----------------连接-------------------}
    function GotoServer(BThread: TIdTCPClient):Boolean;
    begin
       try
         if BThread.Connected then
         BThread.Disconnect;
          BThread.Host:='127.0.0.1';
          BThread.Port:=8201;
          BThread.Connect;
          Result:=True;
        except
          Result:=False;
        end;
    end;
    {----------------发送数据-----------------------}
    procedure SendToClient(AThread: TIdTCPClient;Cmd:String);
    begin
        Try
           if not AThread.Connected then exit;
           AThread.IOHandler.WriteLn(Cmd);
         Except
           AThread.Disconnect;
         end;
    end;
    {----------------创建线程-----------------------}
    constructor TClientThreadone.Create;
    begin
       inherited Create(True);
       FreeOnTerminate:=True;
    end;
    constructor TClientThreadtwo.Create;
    begin
       inherited Create(True);
       FreeOnTerminate:=True;
      IdTCPClient :=TIdTCPClient.Create(nil);
       while not IdTCPClient.Connected  do
         begin
               if gotoserver(IdTCPClient) then
                    SendToClient(IdTCPClient,'comeon');
         end;
    end;
    destructor TClientThreadtwo.Destroy;
    begin
     writeln('线程二:连接断开');
     IdTCPClient.Free;
      inherited destroy;
    end;
    {----------------线程二监听消息--------------------}
    procedure TClientThreadtwo.Execute;
    var
    Str:String;
    begin
      while not Terminated do
      begin
          try
            str:=IdTCPClient.IOHandler.ReadLn();
            writeln('线程二收到消息:'+ str);
         except
          ClientThreadTwo.Destroy;
         end;
        end;
    end;
    {----------------线程一监听消息---------------------}
    procedure TClientThreadone.Execute;
    var
    Str:String;
    begin
      while not Terminated do
      begin
          try
            Str:=IdTCPClient1.IOHandler.ReadLn();
            writeln('线程一收到消息:'+ str);
         except
          ClientThreadOne.Destroy;
         end;
        end;
    end;
    procedure MainConnect;
    begin
       IdTCPClient1 :=TIdTCPClient.Create(nil);
      try
     while not IdTCPClient1.Connected do
     begin
      if GotoServer(IdTCPClient1) then
           begin
                 if not IdTCPClient1.Connected then exit;
                    SendToClient(IdTCPClient1,'comeon');
                     ClientThreadOne:=TClientThreadone.Create;    //创建他们
                     ClientThreadtwo :=TClientThreadtwo.Create ;
           end;
           sleep(5500);
           end;
         ClientThreadOne.Execute;
         ClientThreadTwo.Execute;
     except
       IdTCPClient1.Free ;
       exit;
    end;
    end;destructor TClientThreadone.Destroy;
    begin
      MainConnect;
      inherited destroy;
    end;
    begin
     MainConnect;
    end.单独用一线程就正常,但运行两个线程后两个Execute都不工作,这是怎么回事阿?
      

  4.   

    请参照下面的单元unit TACMWaveInUnit;interfaceuses
      Windows,Classes, IdTCPClient,IdGlobal,ComCtrls,SysUtils,BASE64,MMSystem ,
      soundin,mixing,soundConverter,headers;
    type
      TACMWaveInThread = class(TThread)
      private
        SysThread:TIdTCPClient;
        Acmin1: Tacmin;
        procedure ACMIn1BufferFull(Sender: TObject; Data: Pointer;
        Size: integer);
      protected    procedure Execute; override;
      Public
        constructor Create;
        destructor Destroy; override;
      end;implementation
    uses MainServer;procedure TACMWaveInThread.ACMIn1BufferFull(Sender: TObject; Data: Pointer;
      Size: integer);
    var
     mdata: array[1..512] of char;
     k:integer;
    begin
    try
       for k := 1 to size do
          mdata[k] := pchar(dword(data) + k - 1)^;
       SysThread.WriteBuffer(mdata,Sizeof(mdata));
    except
    end;
    end;constructor TACMWaveInThread.Create;
    var
      origformat: pWaveFormatEX;
      s: array[1..256] of byte;
      F: Tacmwaveformat;
    begin
       inherited Create(True);   SysThread:=TIdTCPClient.Create(nil);
       SysThread.RecvBufferSize:=32768;
       SysThread.SendBufferSize:=32768;
       ACMIn1:= Tacmin.Create(nil);   acmin1.buffersize := 512;
       acmin1.numbuffers := 4;   ACMIn1.onbufferfull:=ACMIn1BufferFull;   GetMem(OrigFormat, Sizeof(TACMWaveFormat));   with origformat^ do
         begin
           wformattag := 49;       // gsm 6.10 2kb
           nchannels := 1;
           nsamplespersec := 8000;
           navgbytespersec := 1625;
           nblockalign := 65;
           wbitspersample := 0;
           cbsize := 2;
           move(origformat^, s, Sizeof(TACMWaveFormat));
           s[18] := 0;
           s[19] := 64;
           s[20] := 1;
           move(s, f.format, sizeof(Tacmwaveformat));
         end;
       freemem(origformat);
       //Acmin1.BufferSize := trunc(f.Format.nAvgBytesPerSec / 20);
       //if Acmin1.buffersize <= f.format.nblockalign then
       //Acmin1.BufferSize := f.format.nblockalign * 2;
       //if Acmin1.buffersize > 1900 then acmin1.buffersize := 1900;
       //if Acmin1.buffersize = 150 then acmin1.BufferSize := 150 + 65;
       try
          Acmin1.Open(f);
       except
          ACMIn1.Close;
       end;   ACMWaveOver:=True;   FreeOnTerminate:=True;
       Suspended := false;
       //Priority:=tpIdle;
    end;
    procedure TACMWaveInThread.Execute;
    var
      Request:String;
    begin
       if H_GZVIP2004.ConRpcport(SysThread) then
         begin
           try
             Request:='005';
             Request:=EncodeBase64(Request);
             SysThread.Write(Request+EOL);
           except
             SysThread.Free;
             Self.Terminate;
             exit;
           end;
           try    //循环发送
             repeat
                Sleep(1);
             until (Terminated) or (SysThread.Connected=False);
           except
           end;
        end;    SysThread.Disconnect;
        SysThread.Free;
    //    Self.Terminate;
    end;destructor TACMWaveInThread.Destroy;
    begin
      ACMWaveOver:=False;
      inherited destroy;
    end;
    end.
      

  5.   

    用多线程,涉及VCL对象的用TThead继承下来的就OK了