ServerSocket 采用stThreadBlocking方式,怎么给指定的客户端发送数据,怎么断开指定的Client

ServerSocket 采用stThreadBlocking方式,如何给指定的客户端发送数据,如何断开指定的Client?
问题:ServerSocket 采用stThreadBlocking方式,如何给指定的客户端发送数据,如何断开指定的Client?

具体描述:当有三个客户端连接进来时,服务端可以显示三个连接进来的客户端,此时我如何能关闭指定(或选定)的已连接进来的客户端,或者说我如果才能向指定(或选定)的客户端发送相关的指令。

说明:这里不考虑客户端的软件问题,客户端是一个产品。

请各位帮忙看看如何可以实现我的那种方法。

个人曾想过使用动态数组定义SvrSocketThr : array of TClientThread,可是不知道如何来做,因为客户端连接进来的个数是不定的,今天可能是三个客户端连接进来,明天也许是二十个客户端连接进来。而且在连接过程有可能断线重连。还请各个帮忙看看...


部份的源码如下:

Delphi(Pascal) code


//在主窗体文件中的部份代码如下:
var  //在这里定义窗体的全局变量
  frmMain: TfrmMain;
  SvrSocketThr :TClientThread;

procedure TfrmMain.SSGetThread(Sender: TObject;
  ClientSocket: TServerClientWinSocket;
  var SocketThread: TServerClientThread);
begin
  // Add Client to lvClient compoment
  AddUser(ClientSocket);
  // Create a new thread for connection
  SvrSocketThr := TClientThread.Create(False, ClientSocket);
  SocketThread := SvrSocketThr;
end;

//线程类中的代码如下:
unit UnitTClientThread;

interface

uses
  Classes,SysUtils, Messages,ScktComp;

type
  TClientThread = class(TServerClientThread)
  private
    { Private declarations }
    FRecText : PChar;
    procedure SetRecText(const Value: PChar);
    procedure ShowMmoReceiveResult();
    procedure DeleteUser();
    procedure DisConnectClientSocket();
    procedure ReceiveClientData();
  protected
    procedure Execute; override;
  public
    SocketStream: TWinSocketStream;
    property RecText:PChar read FRecText write SetRecText;
  end;

implementation

uses UnitMain;

procedure TClientThread.Execute;
Var
  Data: Array[0..1023] Of char;
Begin
  { Place thread code here }
  While (not Terminated) and (ClientSocket.Connected) Do
  Try
    FreeOnTerminate := True;  //线程执行完之后自动关闭并释放线程
    SocketStream := TWinSocketStream.Create(ClientSocket,30000);
    Try
      FillChar(Data, SizeOf(Data), 0);
      if SocketStream.WaitForData(30000) then  // give the client 30 seconds to start writing
      begin
        if Terminated then  //判断是线断是否被关闭
          DisConnectClientSocket //Close Socket
        else
        begin
          if SocketStream.Read(Data, SizeOf(Data)) = 0 then //if can't read in 60 seconds
            DisConnectClientSocket //Close Socket
          else
            ReceiveClientData(); // Receive Data
        end;  
      end
      else
        DisConnectClientSocket; //Close Socket
    Finally
      SocketStream.Free;
    End;
  Except
    HandleException;
  End;
End;

procedure TClientThread.ShowMmoReceiveResult();
begin
  frmMain.mmoReceive.Lines.Add(RecText);
end;

procedure TClientThread.SetRecText(const Value: PChar);
begin
  FRecText := Value;
end;

procedure TClientThread.DeleteUser();
var
  i:Integer;
begin
  for i:=0 to frmMain.lvClient.Items.Count-1 do
   begin
     if frmMain.lvClient.Items[i].Caption=ClientSocket.RemoteAddress then
     begin
       frmMain.lvClient.Items.Item[i].delete;
       frmMain.mmoReceive.Lines.add('时间:'+datetimetostr(now())+' ===== IP为:'+ ClientSocket.RemoteAddress + ':' + IntToStr(ClientSocket.RemotePort) +' 的客户端与服务器断开连接!');
       Break;
     end;
   end;
end;

procedure TClientThread.DisConnectClientSocket();
begin
  // If we didn't get any data after xx seconds then close the connection
  ClientSocket.SendText('SETUP END'+#13#10);
  //Wait a little time to allow sending of text before disconnect
  sleep(1);
  // Delete Client to lvClient compoment
  //Synchronize(DeleteUser);
  DeleteUser;
  // Close ClientSocket
  ClientSocket.Close;
  Terminate;
end;

procedure TClientThread.ReceiveClientData();
begin

end;    

end.







------解决方案--------------------
为每一个连接声明一个类

frmMain.lvClient.Items[i].data 指向这个类

在断开的时候可以取类的定义
------解决方案--------------------
学习了 顶
------解决方案--------------------