如何将从TServerSocket发送流同步到Multi TClientSocket

时间:2017-01-04 17:59:54

标签: sockets delphi asynchronous

有没有一个解决方案可以在delphi的ScktComp.dcu中使用TServerSocket,让我可以将单个文件流或多个文件流同步到Multi TClientSocket ......? 我在这里有这个代码:

procedure TFrmMainServer.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
var 
   a, ACount: integer;
   MyText: String;
   MyBuffer: pchar;
   MyStream: TMemoryStream; //or TFileStream;
begin
...
...
...
  for a := 0 to ServerSocket1.Socket.ActiveConnections - 1 do
  begin
      ServerSocket1.Socket.Connections[a].SendText(MyText);
      // or 
      //ServerSocket1.Socket.Connections[a].SendStream(Mystream); // for files transfering ....
      // or
      //ServerSocket1.Socket.Connections[a].SendBuf(MyBuffer, ACount);
  end;
end;

我真正需要的是用一个好的表达式替换循环函数,这个表达式允许我将任何文件流或任何文本或任何命令传输或发送到多TClientSocket但使用Syncronize方法并且意味着每个与之连接的客户端我的服务器应该收到我的TClientServer同时发送或转移的内容,而不会丢失其他客户端或者一个接一个地等待发送给其他人... 最后,如果有可能在这个组件上,我将感谢任何一个回复的建议,并且非常感谢。

1 个答案:

答案 0 :(得分:3)

如果要将同一条数据发送到多个客户端,则无法避免循环。 TCP根本没有向多个客户端广播数据的概念,因此您必须在代码中手动实现它。这通常意味着为每个客户端单独复制数据,以便他们可以并行发送数据。

有两种方法可以解决这个问题,并且都需要使用每个客户端的出站数据缓冲区。我喜欢使用TServerSocket.OnClientConnect事件为缓冲区创建TMemoryStream并将其分配给TCustomWinSocket.Data属性,以便轻松跟踪它。使用对您的代码有意义的任何内容。

  1. 将服务器置于线程阻塞模式,以便每个客户端都在自己的专用工作线程中运行。用关键部分包装数据缓冲区。当您想要将数据写入特定客户端时,请锁定客户端的缓冲区,将数据附加到缓冲区的末尾,然后将其解锁。让客户端的工作线程不断检查缓冲区是否有新数据,并通过客户端套接字发送。在你去的时候从缓冲区前面删除发送的字节。

  2. 将服务器置于非阻塞模式,因此不使用工作线程或锁。如果要将数据写入特定客户端,请检查客户端缓冲区中是否已包含任何未发送的字节。如果是这样,只需将新字节附加到缓冲区的末尾并继续。否则,尽可能多地将字节发送到客户端套接字,如果发送失败且出现WSAEWOULDBLOCK错误,则将任何未发送的字节附加到缓冲区的末尾。使用TServerSocket.OnClientWrite事件完成从缓冲区发送任何未发送的数据,随时删除缓冲区前面的已发送字节。