用来查询端口连接数的线程,只执行一个线程时能获取最后结果,但是同时执行2个就不行了
    提供完整代码,复制即可用,还请高手分析分析,80分求教。线程代码:
unit Telnets;interfaceuses Windows, Classes, SysUtils, IdTelnet , StrUtils, StdCtrls, Messages, ActiveX;type
  TTelnetThread = class(TThread)
  private
    { Private declarations }
    procedure SendCommand(Command: string);
    procedure Connect;
    procedure LoginDataAvailable(Sender: TIdTelnet; const Buffer: String);
    procedure GetOLDataAvailable(Sender: TIdTelnet; const Buffer: String);
  protected
    procedure Execute; override;
  public
    constructor Create(HostB:string; PortAB:Integer; PortBB:Integer; EditB:TEdit);
  end;var
  Telnet : TIdTelnet;
  OlTemp,OlCount : TStringList;
  EditA : TEdit;
  HostA : string;
  PortAA , PortBA: Integer;
implementationconstructor TTelnetThread.Create(HostB:string; PortAB:Integer; PortBB:Integer; EditB:TEdit);
begin
  FreeOnTerminate := True;
  inherited Create(False);
  HostA := HostB;
  PortAA := PortAB;
  PortBA := PortBB;
  EditA := EditB;
end;procedure TTelnetThread.Execute;
begin
  FreeOnTerminate := True;
  CoInitialize(nil);  Telnet := TIdTelnet.Create(nil);
  Telnet.OnDataAvailable := LoginDataAvailable;  EditA.Text := 'Getting...';  OlTemp := TStringList.Create;
  OlCount := TStringList.Create;
  Connect;
end;procedure TTelnetThread.SendCommand(Command: string);
var
  i : integer;
begin
//  OlTemp.Add(Command);
//  MessageBox(0,PChar(OlTemp.Text),'标题',MB_OK);
  if Telnet.Connected then
  begin
    for i := 1 to length(Command) do
    Telnet.SendCh(Command[i]);
    Telnet.SendCh(#13);
  end;
end;procedure TTelnetThread.Connect;
begin
  Telnet.Host:=HostA;
  Telnet.Port:=PortAA;
  Telnet.Connect;
end;procedure TTelnetThread.LoginDataAvailable(Sender: TIdTelnet; const Buffer: String);
const
    CR = #13;
    LF = #10;
var
    Start, Stop : Integer;
begin
  Start := 1;
  Stop  := Pos(CR, Buffer);
  if Stop = 0 then
      Stop := Length(Buffer) + 1;
  while Start <= Length(Buffer) do begin
 
          if Copy(Buffer, Start, Stop - Start) = 'login: ' then
          begin
            SendCommand('administrator');
          end;
          if Copy(Buffer, Start, Stop - Start) = 'password: ' then
          begin
            SendCommand('password#');
          end;
          if Copy(Buffer, Start, Stop - Start) = 'C:\Users\Administrator>' then
          begin
            Telnet.OnDataAvailable := GetOLDataAvailable;
            OlTemp.Clear;
            OlCount.Clear;
            SendCommand('netstat -an -p TCP | find "'+IntToStr(PortBA)+'"');
          end;      Start := Stop + 1;
      if Start > Length(Buffer) then
          Break;
      if Buffer[Start] = LF then
         Start := Start + 1;
      Stop := Start;
      while (Buffer[Stop] <> CR) and (Stop <= Length(Buffer)) do
          Stop := Stop + 1;
  end;
end;procedure TTelnetThread.GetOLDataAvailable(Sender: TIdTelnet; const Buffer: String);
const
    CR = #13;
    LF = #10;
var
    Start, Stop, i: Integer;
begin
  if OlTemp.Count = 0 then
      OlTemp.Add('');
  Start := 1;
  Stop  := Pos(CR, Buffer);
  if Stop = 0 then
      Stop := Length(Buffer) + 1;
  while Start <= Length(Buffer) do begin
          OlTemp.Strings[OlTemp.Count - 1] :=
          OlTemp.Strings[OlTemp.Count - 1] +
          Copy(Buffer, Start, Stop - Start);          if Copy(Buffer, Start, Stop - Start) = 'C:\Users\Administrator>' then
          begin
            for i := 0 to OlTemp.Count - 1 do
            begin
              if AnsiContainsText(OlTemp.Strings[i], 'ESTABLISHED') then
              OlCount.Add(OlTemp.Strings[i]);
            end;
            EditA.Text:=IntToStr(OlCount.Count);
            SendCommand('Exit');
          end;      if Buffer[Stop] = CR then begin
          OlTemp.Add('');
      end;
      Start := Stop + 1;
      if Start > Length(Buffer) then
          Break;
      if Buffer[Start] = LF then
         Start := Start + 1;
      Stop := Start;
      while (Buffer[Stop] <> CR) and (Stop <= Length(Buffer)) do
          Stop := Stop + 1;
  end;
end;
end.
调用代码unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Button2: TButton;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementationuses Telnets;{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
  thread1:TTelnetThread;
begin
  thread1:=TTelnetThread.Create('172.16.3.100',23,9980,Edit1);end;procedure TForm1.Button2Click(Sender: TObject);
var
  thread2:TTelnetThread;
begin
  thread2:=TTelnetThread.Create('172.16.3.200',23,9980,Edit2);
end;end.

解决方案 »

  1.   

    var
      Telnet : TIdTelnet;
      OlTemp,OlCount : TStringList;
      EditA : TEdit;
      HostA : string;
      PortAA , PortBA: Integer;
    应该放到线程类里面吧
      

  2.   

    var
      Telnet : TIdTelnet;
      OlTemp,OlCount : TStringList;
      EditA : TEdit;
      HostA : string;
      PortAA , PortBA: Integer;
    需要放到线程里,另外不能直接在线程中访问VCL。
      

  3.   

    我是纯新手,你们说的我都半懂不懂,我只要在VCL中能得到OlCount.Count值就可以了,谁帮我修改好贴出来吧谢谢了,我80分全给他,全部家当了。。
      

  4.   

    不要线程里访问VCL或生成(vcl很多是not threadsafe),否则处理起来会负责一些,如果需要用到可以synchronize或者自己sendmessage