俩问题。
  写IdTCPServer.Active:=false;在Delphi里运行总是抛出EIdCloseSocket的异常,前面加上IdTCPClient.Disconnet就好了。但是生成的程序在Windows下运行时关闭却不抛出这个异常了,也没有什么错。这是怎么搞的啊?
  还有,想拿Delphi做一个端口扫描的程序(像防火墙)那样的,能抓到某个已被别的程序占用的端口收到的包,怎么做啊?需要很底层吗?我试了一下,做了两个Server,但只有Client指定连接的那个能收到东西,另外一个死活没动静。那位大生做过或有些眉目,帖出来造福大众啊。

解决方案 »

  1.   

    http://www.programurl.com/packet-sniffer-sdk-for-windows-vcl-edition-.htm
      

  2.   

    Indy屏蔽了这些错误,不过在IDE环境还是会弹出的.
    把sock设置在混杂模式就能监听网络上所有数据了.
      

  3.   

    没人理了?顶一下。
    网上又能找着的vc写的代码(http://www.pcdog.com/network/html/2004831/318200411725_1.htm),但是那个SIO_RCVALL是什么东西?有没有那个老大知道阿?Delphi不认啊。
    还有那个union是不是能用variat代替?
      

  4.   

    -------------serverunit SMain;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls, IdAntiFreezeBase, IdAntiFreeze, IdThreadMgr,
      IdThreadMgrPool, IdBaseComponent, IdComponent, IdTCPServer,ADODB,Provider,DBClient,Activex;type
      TForm1 = class(TForm)
        IdTCPServer1: TIdTCPServer;
        IdThreadMgrPool1: TIdThreadMgrPool;
        IdAntiFreeze1: TIdAntiFreeze;
        GroupBox1: TGroupBox;
        LabeledEdit1: TLabeledEdit;
        LabeledEdit2: TLabeledEdit;
        Button1: TButton;
        Button2: TButton;
        Label1: TLabel;
        Label4: TLabel;
        Label2: TLabel;
        Label3: TLabel;
        Label5: TLabel;
        Label6: TLabel;
        Label7: TLabel;
        GroupBox2: TGroupBox;
        Memo1: TMemo;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure IdTCPServer1Connect(AThread: TIdPeerThread);
        procedure IdTCPServer1Disconnect(AThread: TIdPeerThread);
        procedure IdTCPServer1Execute(AThread: TIdPeerThread);
        procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
      private
        ConnCount,QCount,ACount:Integer;
        ConnStr:String;
        SumTime,BeginTime,EndTime:Cardinal;
        procedure ClearMemo;
        procedure DisplayQinfo;
        procedure DisplayAinfo;
      public
        { Public declarations }
      end;
    var
      Form1: TForm1;implementation{$R *.dfm}{ TForm1 }procedure TForm1.ClearMemo;
    begin
      if Memo1.Lines.Count>30 then
        Memo1.Lines.Delete(0);
    end;procedure TForm1.DisplayAinfo;
    begin
      Inc(ACount);
      Label2.Caption:=IntToStr(ACount);
    end;procedure TForm1.DisplayQinfo;
    begin
      Inc(QCount);
      Label2.Caption:=IntToStr(QCount);
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      if Button1.Caption = '打开监听' then
        begin
          IdThreadMgrPool1.PoolSize := StrToInt(LabeledEdit2.Text);
          IdTCPServer1.DefaultPort := StrToInt(LabeledEdit1.Text); 
          Try
            IdTCPServer1.Active := true;
          except
            On E: Exception do begin
              ShowMessage(E.Message);
              exit;
            end;
          end;
          Button1.Caption := '关闭监听';
          Button2.Enabled := false;
        end
      else
        begin
          try
            IdTCPServer1.Active := False;
          except
            IdTCPServer1.Threads.Clear;
            IdTCPServer1.Active := False;
          end;
          Button1.Caption := '打开监听';
          Button2.Enabled := true;
        end;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      Memo1.Lines.Clear;
      Label1.Caption := '';
      Label2.Caption := '';
      Label3.Caption := '';
      Label7.Caption := '';
    end;procedure TForm1.FormCreate(Sender: TObject);
    var
      ADOConnection:TADOConnection;
      Dname:string;
    begin
      Label1.Caption := '';
      Label2.Caption := '';
      Label3.Caption := '';
      Label7.Caption := '';
      Memo1.Lines.Clear;  Dname:='kn';
      try
        ConnStr := 'Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog='+Dname;    ADOConnection := TADOConnection.Create(nil);
        ADOConnection.ConnectionString := Connstr;
        ADOConnection.Open;
        ADOConnection.Close;
        FreeAndNil(ADOConnection);//将ADOConnection释放并赋为空
      except
        ShowMessage('连接数据库失败!');
        PostMessage(Self.Handle, WM_CLOSE, 0, 0);
      end;
    end;procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
    begin
      BeginTime:=GetTickCount;
      Inc(ConnCount);
      Label1.Caption:='系统连接数:'+IntToStr(ConnCount);
    end;procedure TForm1.IdTCPServer1Disconnect(AThread: TIdPeerThread);
    begin
      Dec(ConnCount);
      Label1.Caption := '系统连接数:' + IntToStr(ConnCount);
      EndTime := GetTickCount;
      try
        SumTime := SumTime + EndTime - BeginTime;
        Label7.Caption := IntToStr(SumTime);
      except
        Label7.Caption := '超出范围,无法显示!';
      end;
      AThread.Connection.Disconnect;
    end;procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
    var
      TempStr: String;
      StrList: TStringList;
      ADOConnection: TADOConnection;
      DataSetProvider: TDataSetProvider;
      ClientDataSet: TClientDataSet;
      ADOQuery: TADOQuery;
      AStream: TStringStream;
      i: integer;
    begin
      AThread.Synchronize(ClearMemo);
      Memo1.Lines.BeginUpdate;
      try
        TempStr := AThread.Connection.ReadLn;
        if AThread.Connection.ReadLnTimedOut then
          begin
            Memo1.Lines.Add('-读客户端信息超时-');
            Memo1.Lines.EndUpdate;
            //AThread.Connection.Disconnect;
          end;
        if Tempstr <> '' then
          begin
            AThread.Synchronize(DisplayQInfo);
            CoInitialize(nil);
            ADOConnection := TADOConnection.Create(Nil);
            ADOConnection.ConnectionString := Connstr;
            ADOConnection.Open;        ADOQuery := TADOQuery.Create(Nil);
            ADOQuery.Connection := ADOConnection;
            ADOQuery.SQL.Text :=TempStr;
            ADOQuery.Open;        AThread.Connection.WriteInteger(0, True);        DataSetProvider := TDataSetProvider.Create(Nil);
            ClientDataSet := TClientDataSet.Create(Nil);
            DataSetProvider.DataSet := ADOQuery;
            ClientDataSet.Data := DataSetProvider.Data;
            AStream:=TstringStream.Create('');        ClientDataSet.SaveToStream(AStream,dfxml);
            AThread.Connection.OpenWriteBuffer;
            AThread.Connection.WriteStream(AStream);
            AThread.Connection.CloseWriteBuffer;
            FreeAndNil(AStream);
            ClientDataSet.Close;
            FreeAndNil(ClientDataSet);
            FreeAndNil(DataSetProvider);
            ADOQuery.Close;
            FreeAndNil(ADOQuery);
            ADOConnection.Close;
            FreeAndNil(ADOConnection);        CoUnInitialize;        AThread.Synchronize(DisplayAInfo);
            //AThread.Connection.Disconnect;
          end;
        //else
          //AThread.Connection.WriteInteger(-1, True);
      except
        On E: Exception do
          Memo1.Lines.Add(E.Message);
      end;  Memo1.Lines.EndUpdate;
    end;
    procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    begin
      IdTCPServer1.Active := False;
      IdAntiFreeze1.Active := False;
    end;end.
      

  5.   

    --------client
    unit CMain;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Grids, StdCtrls, ExtCtrls, ComCtrls, DB, DBClient,
      IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient;type
      TForm1 = class(TForm)
        GroupBox1: TGroupBox;
        LabeledEdit1: TLabeledEdit;
        LabeledEdit2: TLabeledEdit;
        Button1: TButton;
        Button3: TButton;
        GroupBox2: TGroupBox;
        Button4: TButton;
        GroupBox3: TGroupBox;
        StringGrid1: TStringGrid;
        DateTimePicker1: TDateTimePicker;
        DateTimePicker2: TDateTimePicker;
        IdTCPClient1: TIdTCPClient;
        ClientDataSet1: TClientDataSet;
        Button2: TButton;
        ProgressBar1: TProgressBar;
        procedure Button1Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
        procedure Button4Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    begin
      IdTCPClient1.Host := LabeledEdit1.Text;
      IdTCPClient1.Port := StrToInt(LabeledEdit2.Text);
      try
        IdTCPClient1.Connect;
        IdTCPClient1.Disconnect;
      except
        On E: Exception do begin
          ShowMessage(E.Message);
          Exit;
        end;
      end;
      Button2.Click;
    end;procedure TForm1.Button3Click(Sender: TObject);
    begin
      Button4.Enabled := false;
      Button3.Enabled := false;
      Button1.Enabled := true;
      Button2.Enabled := true;
      LabeledEdit1.Enabled := true;
      LabeledEdit2.Enabled := true;
    end;procedure TForm1.Button4Click(Sender: TObject);
    var
      BeginTime, EndTime: Cardinal;
      AStream: TStringStream;
      dr,i:integer;
      Sdate,Edate:string;
      STime:Tdate;
      DTime:Tdatetime;
    begin
      progressbar1.Position:=0;
      if DateTimepicker1.Date > DateTimePicker2.DateTime then
        begin
          ShowMessage('开始日期应小于结束日日期!');
          exit;
        end;
      stringgrid1.RowCount:=2;
      STime:=DateTimepicker1.Date;
      DTime:=DateTimepicker2.Date-DateTimepicker1.Date;
      progressbar1.Max:=trunc(dtime);
      try
        for dr:=0 to trunc(dtime) do
          begin
        Sdate:=formatdatetime('yyyy-mm-dd',Stime+dr)+' 00:00:00';
        Edate:=formatdatetime('yyyy-mm-dd',Stime+dr)+' 23:59:59';
        IdTCPClient1.Connect;
        IdTCPClient1.WriteLn('select address,datetime,a_v,b_v,c_v from ptdata where datetime>='''+Sdate+''' and datetime<='''+Edate+''' order by datetime');
        ProgressBar1.StepBy(1);
        Case IdTCPClient1.ReadInteger(True) of
          0 :
            begin
              AStream := TStringStream.Create('');
              IdTCPClient1.ReadStream(AStream, -1, True);
              AStream.Seek(0, soFromBeginning);
              ClientDataSet1.Close;
              ClientDataSet1.LoadFromStream(AStream);
              if ClientDataSet1.RecordCount<>0 then
                BEGIN
                  stringgrid1.FixedRows:=1;
                end;
              stringgrid1.Cells[0,0]:='address';
              stringgrid1.Cells[1,0]:='datetime';
              stringgrid1.Cells[2,0]:='a_v';
              stringgrid1.Cells[3,0]:='b_v';
              stringgrid1.Cells[4,0]:='c_v';
              for i:=1 to ClientDataSet1.RecordCount do
                begin
                  stringgrid1.Cells[0,stringgrid1.RowCount-1]:=clientdataset1.fieldbyname('address').AsString;
                  stringgrid1.Cells[1,stringgrid1.RowCount-1]:=clientdataset1.fieldbyname('datetime').AsString;
                  stringgrid1.Cells[2,stringgrid1.RowCount-1]:=clientdataset1.fieldbyname('a_v').AsString;
                  stringgrid1.Cells[3,stringgrid1.RowCount-1]:=clientdataset1.fieldbyname('b_v').AsString;
                  stringgrid1.Cells[4,stringgrid1.RowCount-1]:=clientdataset1.fieldbyname('c_v').AsString;
                  stringgrid1.RowCount:=stringgrid1.RowCount+1;
                  ClientDataSet1.Next;
                end;
              FreeAndNil(AStream);
            end;
          -1:
            begin
              ShowMessage('未知的请求类型!');
              exit;
            end;
          -2:
            begin
              ShowMessage('无可用服务器!');
              if IdTCPClient1.Connected then
                IdTCPClient1.Disconnect;
              exit;
            end;
            end;    end;
      except
        On E: Exception do begin
          if IdTCPClient1.Connected then
            IdTCPClient1.Disconnect;
          ShowMessage(E.Message);      exit;
        end;
      end;
      stringgrid1.RowCount:=stringgrid1.RowCount-1;
      IdTCPClient1.Disconnect;
      Button4.Enabled := true;
      EndTime := GetTickCount;end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      Button1.Enabled := false;
      Button2.Enabled := false;
      Button3.Enabled := true;
      Button4.Enabled := true;  LabeledEdit1.Enabled := false;
      LabeledEdit2.Enabled := false;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      datetimepicker1.Date:=strtodate('2004-04-20');
      datetimepicker2.Date:=strtodate('2004-04-20');
    end;end.
      

  6.   

    我是想跳过Delphi封装好的socket组件,直接拿SocketAPI写了。呵呵, jiaai(逍遥游)辛苦了。不过我在网上找到了我要的例子,跟我的本意大致相同,很有参考价值,已经差不多了,谢谢 jiaai(逍遥游)大大了。