Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi TServerSocket和许多TClientSocket_Delphi - Fatal编程技术网

Delphi TServerSocket和许多TClientSocket

Delphi TServerSocket和许多TClientSocket,delphi,Delphi,我有一个TserverSocket和许多TClientSocket。 A可以将文本从所有客户端发送到服务器并正确接收。 但问题是如何将不同的数据从TServerSocket发送到许多不同的客户端。如果我记得,而且我已经有一段时间没有使用Delphi了,TServerSocket有一个可以访问的客户端列表,请检查属性 您还可以在客户端连接/断开连接时将TCustomSocket实例添加/删除到列表中,然后迭代并发送到列表中,尽管如我所说,我非常确定TServerSocket在内部具有此功能。管理/

我有一个TserverSocket和许多TClientSocket。 A可以将文本从所有客户端发送到服务器并正确接收。
但问题是如何将不同的数据从TServerSocket发送到许多不同的客户端。

如果我记得,而且我已经有一段时间没有使用Delphi了,TServerSocket有一个可以访问的客户端列表,请检查属性


您还可以在客户端连接/断开连接时将TCustomSocket实例添加/删除到列表中,然后迭代并发送到列表中,尽管如我所说,我非常确定TServerSocket在内部具有此功能。

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

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;
var-connectedSocketHandle:integer;
.
.
.
t服务器1客户端连接(发送方:ToObject;
套接字:TCustomWinSocket);
开始

connectedSocketHandle:=Socket.SocketHandle;{你可以使用优秀的(免费的)ICS库,有了它,您就有了一个具有多个客户端的TCP服务器的好例子。

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

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

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.

这对你有用吗?

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

仅供参考观看此PLZ的任何人仔细看看“Remy Lebeau”在其回答中所说的内容,他是100%正确的,只是没有留下任何源代码可供参考

好的,让我们开始吧,基本上为了“从TServerSocket发送到特定的客户端”,您必须设计自己的连接“列表”,并将它们应用到每个连接TClientSocket的Tcustomwinsock.Data属性,如Remy在回答中所说

如果你到目前为止还不明白,就继续读下去吧,我相信一切都会很快弄清楚的

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

type TConnectionInfo = record
                          UserID : string;
                          Socket : TCustomWinSocket; // THIS IS VERY IMPORTANT!!! Do not FORGET it
                   end;
创建TConnectionInfo记录后,您可以进入下一部分,即创建指向TConnectionInfo记录的“指针”,以便在您的私有或公共声明下添加:

var
Connection: ^TConnectionInfo;
完成后,我们可以转到ServerSocketClientConnect事件过程,在该过程中,我们将开始通过TConnectionInfo记录建立连接列表<每个连接的客户端都有一个连接

因此,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;
好的,那么如果你一直关注我,接下来是有趣的部分,你会问“如何发送到特定客户机”一旦你有了上述代码设置,通过上面编码的“UserID”发送到一个特定客户机是非常容易的。为了简单起见,我将把它放在一个按钮点击事件过程中:

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;
现在请记住,只是因为您现在可以按您想要的方式发送,您还没有完成。您必须了解,因为您正在为每个连接使用自己的自定义记录列表,所以在每个客户端与服务器断开连接时,您还必须相应地“释放”该内存……如下所示:

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组件的客户端。

我找不到方法。我无法命名客户端并将其发送到我想要的位置。客户端由IP地址标识。当然,您可以从一个IP地址拥有多个客户端ess(即一台机器)所有插座都打开,连接到一台服务器。你需要决定如何区分它们。这似乎有点过头了。一旦他切换到ics,他会问自己同样的问题:)这不是一个有用的答案。+1(TClientsocket和TServersocket已被弃用-因此问题将再次出现)您不应使用SocketHandle作为ID。关闭的句柄可以重新用于新连接。您需要使用自己的ID值(将它们存储在TCustomWinSocket.Data属性中),或者改为使用它们唯一的IP/端口对来标识连接。