当serversocket有多个clientsocket连接的时候,serversocket想给某一个clientcocket发信息时,怎么发送,我查过资料,这样实现:
      ServerSocket.Socket.Connections[i].SendText('dfsd');
这样实现可以,但我不知道有一个客户端对应的是哪一个连接,而且当某一个客户端退出之后,其他客户端的顺序是否会变化,谢谢,不知道我是否表达明白

解决方案 »

  1.   

    我给你一个例子unit main;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, ScktComp, Menus, StdCtrls;
    type
    session_record=record
       Used: boolean; {会话记录是否可用}
       SS_Handle: integer; {代理服务器套接字句柄}
       CSocket: TClientSocket; {用于连接远程的套接字}
       Lookingup: boolean; {是否正在查找服务器}
       LookupTime: integer; {查找服务器时间}
       Request: boolean; {是否有请求}
       request_str: string; {请求数据块}
       client_connected: boolean; {客户机联机标志}
       remote_connected: boolean; {远程服务器连接标志}
    end;type
      TForm1 = class(TForm)
        ServerSocket1: TServerSocket;
        ClientSocket1: TClientSocket;
        Timer1: TTimer;
        Timer2: TTimer;
        MainMenu1: TMainMenu;
        N1: TMenuItem;
        N11: TMenuItem;
        N21: TMenuItem;
        N01: TMenuItem;
        Memo1: TMemo;
        GroupBox1: TGroupBox;
        Label1: TLabel;
        Edit1: TEdit;
        Button1: TButton;
        Label2: TLabel;
        Edit2: TEdit;
        Memo2: TMemo;
        procedure Timer2Timer(Sender: TObject);
        procedure N11Click(Sender: TObject);
        procedure N21Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure N01Click(Sender: TObject);
        procedure ServerSocket1Listen(Sender: TObject;
          Socket: TCustomWinSocket);
        procedure ServerSocket1ClientConnect(Sender: TObject;
          Socket: TCustomWinSocket);
        procedure ServerSocket1ClientDisconnect(Sender: TObject;
          Socket: TCustomWinSocket);
        procedure ServerSocket1ClientError(Sender: TObject;
          Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
          var ErrorCode: Integer);
        procedure ServerSocket1ClientRead(Sender: TObject;
          Socket: TCustomWinSocket);
        procedure ClientSocket1Connect(Sender: TObject;
          Socket: TCustomWinSocket);
        procedure ClientSocket1Disconnect(Sender: TObject;
          Socket: TCustomWinSocket);
        procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
          ErrorEvent: TErrorEvent; var ErrorCode: Integer);
        procedure ClientSocket1Write(Sender: TObject;
          Socket: TCustomWinSocket);
        procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
        procedure Timer1Timer(Sender: TObject);
        procedure AppException(Sender: TObject; E: Exception);
        procedure Button1Click(Sender: TObject);  private
        { Private declarations }
      public
        { Public declarations }
        Service_Enabled: boolean; {代理服务是否开启}
        session:array of session_record; {会话数组}
        sessions: integer; {会话数}
        LookUpTimeOut:integer; {连接超时值}
        InvalidRequests:integer; {无效请求数} 
      end;var
      Form1: TForm1;
      

  2.   

    implementation{$R *.dfm}procedure TForm1.Timer2Timer(Sender: TObject);
    begin
      timer2.Enabled:=false; {关闭定时器}
      sessions:=0; {会话数=0}
      Application.OnException:=AppException; {为了屏蔽代理服务器出现的异常}
      invalidRequests:=0; {0错误}
      LookUpTimeOut:=120000; {超时值=1分钟}
      timer1.Enabled:=true; {打开定时器}
      n11.Enabled:=false; {开启服务菜单项失效}
      n21.Enabled:=true; {关闭服务菜单项有效}
      if Edit2.Text<>'' then
         try
           serversocket1.Port:=StrToInt(Edit2.Text);
         except
           serversocket1.Port:=988; {代理服务器端口=988}
         end;
           serversocket1.Active:=true; {开启服务}  
      //form1.hide; {隐藏界面,缩小到System Tray上}
    end;procedure TForm1.N11Click(Sender: TObject);
    begin
       serversocket1.Active:=true; {开启服务} 
    end;procedure TForm1.N21Click(Sender: TObject);
    begin
        serversocket1.Active:=false; {停止服务}
        N11.Enabled:=True;
        N21.Enabled:=False;
        Service_Enabled:=false; {标志清零} 
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
        Service_Enabled:=false;
        timer2.Enabled:=true; {窗口建立时,打开定时器}
    end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
        timer1.Enabled:=false; {关闭定时器}
        if Service_Enabled then
           serversocket1.Active:=false; {退出程序时关闭服务} 
    end;procedure TForm1.N01Click(Sender: TObject);
    begin
       Close;
    end;procedure TForm1.ServerSocket1Listen(Sender: TObject;
      Socket: TCustomWinSocket);
    begin
        Service_Enabled:=true; {置正在服务标志}
        N11.Enabled:=false;
        N21.Enabled:=true;
    end;
      

  3.   

    procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    var
    i,j: integer;
    begin
        j:=-1;
        for i:=1 to sessions do {查找是否有空白项}
        if not session[i-1].Used and not session[i-1].CSocket.active then
        begin
          j:=i-1; {有,分配它}
          session[j].Used:=true; {置为在用}
          break;
        end
        else
        if not session[i-1].Used and session[i-1].CSocket.active then
           session[i-1].CSocket.active:=false;
        if j=-1 then
        begin {无,新增一个}
            j:=sessions;
            inc(sessions);
            setlength(session,sessions);
            session[j].Used:=true; {置为在用}
            session[j].CSocket:=TClientSocket.Create(nil);
            session[j].CSocket.OnConnect:=ClientSocket1Connect;
            session[j].CSocket.OnDisconnect:=ClientSocket1Disconnect;
            session[j].CSocket.OnError:=ClientSocket1Error;
            session[j].CSocket.OnRead:=ClientSocket1Read;
            session[j].CSocket.OnWrite:=ClientSocket1Write;
            session[j].Lookingup:=false;
        end;
        session[j].SS_Handle:=socket.socketHandle; {保存句柄,实现绑定}
        session[j].Request:=false; {无请求}
        session[j].client_connected:=true; {客户机已连接}
        session[j].remote_connected:=false; {远程未连接}
        edit1.text:=inttostr(sessions); 
    end;procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    var
     i,j,k: integer;
    begin
       for i:=1 to sessions do
       if (session[i-1].SS_Handle=socket.SocketHandle) and session[i-1].Used then
       begin
         session[i-1].client_connected:=false; {客户机未连接}
         if session[i-1].remote_connected then
            session[i-1].CSocket.active:=false {假如远程尚连接,断开它}
         else
            session[i-1].Used:=false; {假如两者都断开,则置释放资源标志}
         break;
       end;
       j:=sessions;
       k:=0;
       for i:=1 to j do {统计会话数组尾部有几个未用项}
       begin
       if session[j-i].Used then
          break;
       inc(k);
       end;
       if k>0 then {修正会话数组,释放尾部未用项}
       begin
           sessions:=sessions-k;
           setlength(session,sessions);
       end;
       edit1.text:=inttostr(sessions);
    end;procedure TForm1.ServerSocket1ClientError(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
    var
    i,j,k: integer; 
    begin
       for i:=1 to sessions do
       if (session[i-1].SS_Handle=socket.SocketHandle) and session[i-1].Used then
       begin
         session[i-1].client_connected:=false; {客户机未连接}
         if session[i-1].remote_connected then
            session[i-1].CSocket.active:=false {假如远程尚连接,断开它}
         else
            session[i-1].Used:=false; {假如两者都断开,则置释放资源标志}
         break;
       end;
       j:=sessions;
       k:=0;
       for i:=1 to j do
       begin
         if session[j-i].Used then
            break;
         inc(k);
       end;
       if k>0 then
       begin
         sessions:=sessions-k;
         setlength(session,sessions);
       end;
       edit1.text:=inttostr(sessions);
       errorcode:=0;
    end;procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    var
      tmp,line,host: string;
      i,j,jurl,lineindex,port: integer;
    begin
       for i:=1 to sessions do {判断是哪一个会话}
       if session[i-1].Used and (session[i-1].SS_Handle=socket.sockethandle) then
       begin
          session[i-1].request_str:=socket.ReceiveText; {保存请求数据}
          tmp:=session[i-1].request_str; {存放到临时变量}
          memo1.lines.add(tmp);      if memo1.Lines.Count>3000 then
             memo1.Lines.Clear;      j:=pos(char(13)+char(10),tmp); {一行标志}
          while j>0 do {逐行扫描请求文本,查找主机地址}
          begin
             line:=copy(tmp,1,j-1); {取一行}
             delete(tmp,1,j+1); {删除一行}
             j:=pos('Host',line); {主机地址标志}
             jurl:=pos('Referer',line);
             if jurl>0 then
             begin
                delete(line,1,jurl+8);
                lineindex:=Memo2.Lines.IndexOf(line);
                if lineindex>=0 then
                  memo2.Lines.Delete(lineindex);
                memo2.lines.add(line);
             end;
             if j>0 then
             begin
               delete(line,1,j+5); {删除前面的无效字符}
               j:=pos(':',line);
               if j>0 then
               begin
                 host:=copy(line,1,j-1);
                 delete(line,1,j);
                 try
                   port:=strtoint(line);
                 except
                   port:=80;
                 end;
               end
               else
               begin
                host:=trim(line); {获取主机地址}
                port:=80;
               end;
               if not session[i-1].remote_connected then {假如远征尚未连接}
               begin
                 session[i-1].Request:=true; {置请求数据就绪标志}
                 session[i-1].CSocket.host:=host; {设置远程主机地址}
                 session[i-1].CSocket.port:=port; {设置端口}
                 session[i-1].CSocket.active:=true; {连接远程主机}
                 session[i-1].Lookingup:=true; {置标志}
                 session[i-1].LookupTime:=0; {从0开始计时}
               end
               else
                {假如远程已连接,直接发送请求}
                session[i-1].CSocket.socket.sendtext(session[i-1].request_str);
              break; {停止扫描请求文本}
            end;
           j:=pos(char(13)+char(10),tmp); {指向下一行}
       end;
       break; {停止循环}
       end;
    end;
      

  4.   

    收到,好文借楼主的宝地,说一下我的疑问
    每次TForm1.ServerSocket1ClientDisconnect
    都从for i:=1 to sessions do ,假如是上万个连接。
    有没有快捷的方法呢
    比如依据每个连接的ip、port来处理
    可是我找不到port的取得方法