看看Delphi的DEMO
写得很清楚

解决方案 »

  1.   

    你可以自定义一个自己的线程类从tthread继承,把winsocket和ip(或者其他的你的数据和标志位)定义为该类的私有成员。类的execute方法里connect远程主机。而且应该将socket设置成阻塞模式。
    另外,tthread会返回一个值,可能对你有用。
    :)
      

  2.   

    写一个管理类,管理线程,线程是TCleintSocket连接IP地址
    管理类中开启一定数量的线程,没有达到数量则新开,到达一定数量后则等待。继承TClientSocket,加入一个空闲标志,将它的ClientType=ctBlock线程类中加入一个标志:是否完成,完成后,将TClientSocketEx的空闲标志置False,并进入等待(不必Free Thread,当工作完成后再Free Thread)
      

  3.   

    to:: outer2000(天外流星) 
    不是要做黑客呀。。
    我是检测局域网内的IP地址;TO:chenjbjbjb(哈哈) (
    谢谢!!
    我试试。。To:: wisenowa(无人喝彩) 
    那个demo
      

  4.   

    To:copy_paste(落泊的木石三) :能否给点示例代码:
    要知道我刚刚能看懂你在说什么。。
    至于怎么来写我无从下手
    不好意思
      

  5.   

    借花
    //**********************************************************************************
    //说明: TServerSocket阻塞线程
    //作者: licwing          时间: 2001-4-21
    //Email: [email protected]
    //**********************************************************************************
    unit BlockThread;interfaceuses SysUtils, Windows, Messages, Classes, ScktComp,ProxyCnt;type
      TBlockThread = Class(TServerClientThread)
      private
        FWebClient: TClientSocket; //对web进行数据请求
        FWebClientRead: Boolean; //是否可以对web进行数据请求
        FRequestInfo: string;
        FReceiveInfo: TReceiveInfo; //接收的数据流信息
        FRecBytesFromWebSend: Integer; //已接收到的Web数据字节数
        FWebSendBytes: Integer; //Web服务器需要发送的总字节数
      
        Receive_buf: array[0..8191] of char; //接收缓冲区
        Request_buf: array[0..8191] of char; //发送缓冲区,用来保存客户端的请求数据
        Request_buf_bytes: integer; //发送缓冲区已经接收的字节数
        FReceiveInfoSaved : boolean ; //接收的数据头信息保存标志    procedure  InitThread;
        function  SetWebClientInfo(FRequestURLInfo: String): boolean;
      protected
        procedure ClientExecute; override;
        procedure DoTerminate; override;
      public
        constructor Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket);
        destructor Destroy; override;
      end;implementation//TProxyClientThread
    constructor TBlockThread.Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket);
    begin
      FWebClient := TClientSocket.Create(nil);
      FWebClient.ClientType := ctBlocking;  inherited Create(CreateSuspended,ASocket);
      InitThread;
    end;destructor TBlockThread.Destroy;
    begin
      FWebClient.Free;
      inherited Destroy;
    end;procedure TBlockThread.InitThread;
    begin
      FRecBytesFromWebSend := 0;
      FWebSendBytes := 0;
      Request_buf_bytes := 0;
      FReceiveInfoSaved := false;
      FWebClientRead := false;
    end;function TBlockThread.SetWebClientInfo(FRequestURLInfo: String): boolean;
    var
      URL_info: TURLHostInfo;
      FWebFilter: boolean;
    begin
      URL_info := GetURLHostPort(FRequestURLInfo);
      Result := ( URL_info.HostName <> '' ) and ( URL_info.HostPort > 0 );
      FWebClient.Port := URL_info.HostPort;
      FWebClient.Host := URL_info.HostName;
    end;procedure TBlockThread.DoTerminate;
    begin
      FRecBytesFromWebSend := 0;
      FWebSendBytes := 0;
      FRequestInfo := '';
      FReceiveInfoSaved := false;
      FWebClientRead := false;
      inherited DoTerminate;
    end;procedure TBlockThread.ClientExecute;
    var
      ReceiveStream,
      RequestStream: TWinSocketStream;
      Rec_Bytes: integer;
    begin
    //获取和处理命令直到连接或线程结束
      while (not Terminated) and (ClientSocket.Connected) do
        try //try 1
          //创建TWinSocketStream对被代理端进行读写操作
          RequestStream := TWinSocketStream.Create(ClientSocket, 60000);
          try  //try 2
            //获取被代理端请求
            Request_buf_bytes := RequestStream.Read(Request_buf,8192);
            //如果有请求,设置Web端信息
            if Request_buf_bytes > 0 then FWebClientRead := SetWebClientInfo(Request_buf);
            //Web端通信准备完成,并且访问站点没有被过滤  IfID=1
            if FWebClientRead  then 
              begin //IFID=1 begin Then method
              try  //try 3
                //Web端开始通信
                ReceiveStream := TWinSocketStream.Create(FWebClient.Socket, 60000);
                FWebClient.Active := True;
                  try //try 4
                    //向Web端发送请求
                    ReceiveStream.Write(Request_buf,Request_buf_bytes);
                    while (not Terminated) and (FWebClient.Socket.Connected) do
                    begin
                      //接收Web端返回的数据
                      Rec_bytes := ReceiveStream.Read(Receive_buf,8192);                  Inc(FRecBytesFromWebSend,Rec_bytes);
                      //保存Web端返回数据的信息
                      if not FReceiveInfoSaved then
                        begin
                          FReceiveInfo := AnalyzeReceiveData(Receive_buf);
                          FReceiveInfoSaved := FReceiveInfo.ContentInfo.RequestFound;
                          FWebSendBytes := FReceiveInfo.ContentInfo.ContentSize +
                                      FReceiveInfo.RemoteFileInfo.RemoteFileSize;
                        end;
                      //如果被代理端还连接,传送Web端返回的数据
                      if ClientSocket.Connected then                  RequestStream.Write(Receive_buf,Rec_Bytes);
                      if ( FRecBytesFromWebSend >= FWebSendBytes ) or ( Rec_bytes = 0 )
                      or not ClientSocket.Connected then FWebClient.Close;
                    end;
                  finally  //try 4
                    ReceiveStream.Free;
                  end;
              finally  //try 3
                ClientSocket.Close;
              end;
            end  //IFID=1 end Then method
            else //IFID=1 begin else method
              begin//发送拒绝请求信息到客户端
              // RequestStream.Write(AccessLimit,sizeof(AccessLimit));
              end;
          finally  //try 2
            RequestStream.Free;
            Terminate;
          end;
        except  //try 1
          // HandleException;
        end;
    end;end.
    //**********************************************************************************
    // TServerSocket阻塞线程调用方法
    //**********************************************************************************
    procedure TfrmMain.ServerSocketGetThread(Sender: TObject;
      ClientSocket: TServerClientWinSocket;
      var SocketThread: TServerClientThread);
    begin
      SocketThread := TBlockThread.Create(false,ClientSocket);
    end;
      

  6.   

    我真不明白老是有人它的ClientExecute循环中不断的创建TWinSocketStream,然后Free,这是Delphi的示例代码,为什么照抄不勿。TMySocket = class(TClientSocket)
    private
      IsUse: Boolean;
    public
      constructor Create(AOwner: TComponent);// init socket.ClientType
    end;TMyThread = class(Thread)
    private
      FMySocket: TMySOcket;
    protected
      procedure Execute;
    public
      procedure ConnectToIP(IP: string);
    end;procecure ConnnectToIP(IP: string);
    begin
      PostThreadMessage(ThreadID, WM_Connect, 0, Integer(Pointer(PChar(IP))));
    end;procedure Execute;
    begin
      while GetMessage(msg, 0, 0, 0) do
      begin
        if Msg.msg = WM_Connect do
        begin
          FMySocket.Address := PChar(Pointer(msg.lParam));
          try
            FMYSOcket.Open;
          except
            //自已处理
          end;
        end //other message;
        else if msg.message = WM_EXIT then break;//exit loop
      end;
    end;TThreadManage = class
    private
      FList: TList;
    public
      procedure Work;
      procedure Stop;
    end;const
      MAX_ThreadNum = 10;
    procedure Work;
    var
      Obj: TMyThread;
    begin
      for i := 0 to MAX_ThreadNum - 1 do  
      begin
        Obj := TMyThread.Create(False);
        Obj.ConnectToIP('a ip');
      end;
    end;不是很清楚了,随更打了几行,
    反正在TThreadManage中管理好线程,用PostThreadMessage进行与各线程交互,通知线程工作就可以了。
      

  7.   

    TO:cd_fsy2000(书到学时恨他多,钱到用时方恨少) 
    ProxyCnt文件在那??
      

  8.   

    这样好了,动态生成TClientSocket,加到TList中,空闲的就删掉,要用就生成一个放到TList中,这样就没有判断的问题了.并且可以无限多个socket
      

  9.   

    当然是理论上的,实际使用我想一两百个是没问题的.其实你这个是数据结构的问题,而不是winsock的问题
      

  10.   

    你的不是只有6个winsock吗?
      

  11.   

    TO:cd_fsy2000(书到学时恨他多,钱到用时方恨少) “书到学时恨他多,钱到用时方恨少”  这句话好经典! 
      

  12.   

    说错了,我是说要有上1000个记录,用这6个winsock来循环实现。。
      

  13.   

    那是我理解错了.
    你原来的想法非常好.6个异步的 winsock根本不必用多线程.你按你自己的方案做好了.没问题的
      

  14.   

    问题是现在我没法子让这6个winsock同时去工作,也就是这6个winscok怎么可以像你说的那样谁连谁的IP而不相互干扰,现在我只能是一个winsock工作,不能让他6个都工作,
      

  15.   

    这是数据结构的问题1000个ip作为一个队列,用函数GetIP来取得下一个IP
    6个 winsock组成一个数组while (true)
      for (int i=0;i<6;i++)
         if (!winsock[i]->Active)
         {
            GetIP;
            //对取出来的ip做你自己的操作
         }
      

  16.   

    delphi中有队列吗??
    还有6个winsock控件是设计时就放到去的,怎么才可以组成数据呢??
      

  17.   

    还是动态生成数组吧,不要直接放上去
    队列嘛,用链表模拟一下 TList
      

  18.   

    动态生成数组??
    那怎么来触发winsock的那些个事件如connect,error,dataarrival等事件??
    怎么来写??
      

  19.   

    var
      Form1: TForm1;
      pSocket : array [1..5] of TClientSocket;
    implementation{$R *.DFM}procedure TForm1.FormCreate(Sender: TObject);
    var
      i: integer;
    begin
       for i:=0 to 5 do
         pSocket[i] := TClientSocket.Create(nil);
    end;下午我接着写
      

  20.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,scktcomp;type
      TForm1 = class(TForm)
        ClientSocket1: TClientSocket;
        ClientSocket2: TClientSocket;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
         //  定义一个函数来响应 TClientSocket 的  On Connect 时间
        procedure OnMyConnect(Sender: TObject;Socket: TCustomWinSocket);
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      pSocket : array [1..5] of TClientSocket;
    implementation{$R *.DFM}procedure TForm1.FormCreate(Sender: TObject);
    var
      i: integer;
    begin
    //创建控件
       for i:=0 to 5 do
       begin
         pSocket[i] := TClientSocket.Create(nil);
         pSocket[i].OnConnect := Form1.OnMyConnect;  //把自己的函数和TClientSOcket的时间联系起来
       end
    end;procedure TForm1.FormDestroy(Sender: TObject);
    var
      i: integer;
    begin
    //删除控件
       for i:=0 to 5 do
         pSocket[i].Free;
    end;
    procedure TForm1.OnMyConnect(Sender: TObject;Socket: TCustomWinSocket);
    begin
         //  在这个函数里处理  连接  事件
    end;end.应该能看懂吧。
      

  21.   

    对了,其他事件如:OnRead你类推就能写出来了
      

  22.   

    那你就多创建几个winsock.不过但单线程还是5-6个就差不多了,多了不好。
    至于ip大于6个,最简单和最蠢但是最可靠的办法,在一个TTimer中while (true)
    for (int i=0;i<6;i++)
    if (!winsock[i]->Active)
    {
      GetIP;
      //把取出来的ip用winsock连接
    }ip可以用动态数组,也可以用TStrings,也可以TLists
      

  23.   

    后台就要用线程了,在线程里用winsock的话最好用api, 好象delphi的TClientSocket不能在线程里用(我没试过,我想TClientSocket的I/O端口模式是窗口消息模式的,所以没窗口不行)
    如果一个窗口有1-3个winsock,并且数据量不大,那么对窗口操作没什么影响的。
    还有一个办法,就是用mdi,把winsock放在子窗口中。
      

  24.   

    哈哈哈哈,只好多线程,或者mdi.
    我看你你经验不足,还是mdi吧,放3个子窗口,每个10个winsock,这样总可以了吧
      

  25.   

    对了,数据量大?每个 winsock数据量大?大到什么程度?你想做什么?
      

  26.   

    一次可能会有几千个或者几万个字符发过来的??
    或者发过去吧!!
    还不够大呀??
    对了MDI的窗口呀。。
    我还用过了。。
      

  27.   

    我是根本就没有经验了。。
    MDI也没有用过。。
      

  28.   

    这不会太难吧
    我以前写过一个扫描端口的控制台程序,用vc写的不过都是用api这几天我有时间的话写一个用完成端口的玩玩,
    哪你帮我测试如何?