TServerSocket和许多TClientSocket

时间:2011-01-31 10:05:35

标签: delphi

我有一个TserverSocket和许多TClientSocket。 可以将SendText从所有客户端发送到服务器并进行核心接收。 但问题是如何将TServerSocket中的不同数据发送给许多不同的客户端。

6 个答案:

答案 0 :(得分:3)

每个客户端都存储在服务器的Connections列表中。只需找到要发送到的特定客户端的TCustomWinSocket对象即可。通过它们使用的两个IP /端口对(本地和远程)在OS层识别套接字连接。或者,您可以为每个客户的TCustomWinSocket.Data属性分配更有意义的ID(用户名等)。

答案 1 :(得分:2)

我不完全确定我理解这个问题,但我已经写了这个解决方案:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp;

type
  TForm1 = class(TForm)
    ServerSocket1: TServerSocket;
    procedure ServerSocket1Accept(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  hnd:array[1..1024] of integer;
  txt:array[1..1024] of string;
  ser,counter : integer;
implementation

{$R *.dfm}

procedure TForm1.ServerSocket1Accept(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  ser:= Socket.SocketHandle;
    inc(counter);
    hnd[counter]:=ser;
    txt[counter]:='You are number '+IntToStr(counter);
end;


procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
 var t:Integer;
begin
    ser:= Socket.SocketHandle;
    for t:=1 to counter do
    begin
      if hnd[t]=ser then socket.SendText(txt[t]+#13);
    end;
end;

end.

这对你有用吗?

答案 2 :(得分:1)

管理/识别客户端套接字连接的最简单方法是使用其唯一的套接字句柄。

var connectedSocketHandle : integer;
.
.
.
TForm1.server1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);

begin
    connectedSocketHandle:= Socket.SocketHandle; {<--- this is the socket handle of the      client that just connected ..}    
end;

 procedure TForm1.SendMsgToOneSpecificClient(const MsgData: string;
    SocketServer: TServerSocket; uniqueSocketHandle: integer);
 begin
   for x := 0 to socket.Socket.ActiveConnections - 1 do
    begin
      try
        if SocketServer.Socket.Connections[x].SocketHandle = uniqueSocketHandle then
          SocketServer.Socket.Connections[x].SendText(MsgData);
      except
          {....}
      end;
    end;
end;

答案 3 :(得分:1)

我意识到这个答案是晚了,但我只是觉得有人应该介入并在这里给出一个实际的书面答案,以防万一有一天其他人来寻求相同的信息。

仅供参考这个PLZ的人,可以好好看看&#34; Remy Lebeau&#34;在他的回答中说他100%正确,他只是没有留下任何源代码。

好的,让我们开始,基本上是为了从#TServerSocket发送给特定客户端&#34;你必须设计自己的&#34; List&#34;连接并将它们应用于每个连接TClientSocket的Tcustomwinsock.Data属性,正如Remy在他的回答中所说的那样。

如果你到目前为止还不明白,请继续阅读,我相信一会儿就会明白一切。

在Delphi服务器应用程序的顶部添加以下TYPE记录:

type TConnectionInfo = record
                          UserID : string;
                          Socket : TCustomWinSocket; // THIS IS VERY IMPORTANT!!! Do not FORGET it
                   end;

创建TConnectionInfo Reccord之后,您可以继续下一部分,即创建一个&#34; Pointer&#34;在TconnectionInfo Reccord中,根据您的私人声明或公开声明,您只需添加:

var
Connection: ^TConnectionInfo;

完成后我们可以转到ServerSocketClientConnect事件过程,我们将开始通过TConnectionInfo Reccords&lt;建立连接列表。每个连接的客户端都会有一个。

所以serversocketclientconnect事件过程看起来应该是这样的:

procedure TfMain.ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket);
Begin

       GetMem(Connection,sizeof(TConnectionInfo));
       try
       Connection^.UserID := ServerSocket.reciveText; //So when someone connects make them send their username / ID or whatever
       Connection^.Socket := Socket; // This is the important part you will be setting the current socket connection to the "TCustomWinsock" for this connection.
       Socket.Data := Connection; // Now comes the part where you assign the Tcustomwinsock.data property to This instance of the Connection Reccord
       except
       freemem(Socket.Data);
       socket.Close;
       end;
       end;
end;

好的,如果你到目前为止跟随我,接下来就是你要问的有趣的部分&#34;如何发送给特定的客户&#34;一旦你有上面的代码设置,通过他们的用户ID&#34;发送到一个特定的客户端是非常容易的。如上所述。为了简单起见,我将把它放在按钮点击事件过程中:

Procedure TForm1.Button1Click(Sender: TObject);
var 
scan: integer; // scan is the integer count used to Gather all the active connections.
tempcon: ^TConnectionInfo; // Tempcon is going to be used as a pointer to the Connection reccords so we can go though them and send to only a specific Client via his or her UserID :) 
      begin
      try
        for scan := 0 to ServerSocket.Socket.ActiveConnections-1 do
          begin
            TempCon := ServerSocket.Socket.Connections[scan].Data;
            if (TempCon^.UserID = 'The User ID of the person you want to send to') then
               ServerSocket.Socket.Connections[scan].SendText( 'Text you want to send to them!' ); // and this is where the serversocket will send to only one Person via their TcustomWinsock.data property and it will only send to the user with the UserID you specified in the line above.
          end;

现在请记住,因为你现在可以发送,你还没有完成。你必须明白,因为你为每个连接使用自己的自定义Reccords列表,你还必须&#34; Free&#34;相应的内存,因为每个客户端都与服务器断开连接....所以像这样:

procedure TfMain.ServerSocketClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);

begin
  freemem(Socket.Data); // so this code will Free the socket.data which is actually the Record associated with this specific Client Connection.
end;

我希望这有助于海报和其他任何可能来寻求有关如何正确管理连接到TServerSocket vcl组件的客户端的信息的人。

答案 4 :(得分:0)

如果我记得,并且我还没有使用Delphi很长一段时间,TServerSocket有一个你可以访问的客户列表,检查属性。

当客户端连接/断开连接时,你也可以在列表中添加/删除TCustomSocket实例,然后只是迭代它并发送到那里,尽管我说过,我很确定TServerSocket无论如何都在内部。

答案 5 :(得分:0)

您可以使用优秀的(免费)ICS库http://www.overbyte.be/,您可以使用多个客户端的TCP服务器。

相关问题