Delphi 2007,Indy 10 - 用于单向传输数据 block 的最简单的 TCP/IP 设置是什么

标签 delphi tcp network-programming delphi-2007 indy10

我有一个应用程序(“服务器”),它每秒更新内存中的一个数据 block (大约 100k 字节)。

同一网络上的其他工作站上运行着 1 到 4 个“客户端”应用程序的其他实例,这些实例需要每秒读取相同的 100k 图像。

到目前为止,这是通过将图像写入服务器上的文件并让客户端通过网络从该文件读取来实现的。这多年来一直没有任何问题,但最近(与迁移到基于 Windows 8 的硬件同时发生)它出现了一个问题,即除一个节点之外的所有节点都无法访问该文件。退出在此节点上运行的客户端应用程序会释放该文件,然后每个人都可以再次访问该文件。

我仍然对这次锁定的原因感到困惑,但我想知道这是否可能是讨论的机制 here ,其中文件由于网络故障而未关闭。我认为让客户端通过 TCP/IP 请求数据可以避免这种情况。

除了客户端无法连接或读取数据之外,不需要任何握手 - 服务器只需要处理它的业务并通过抓取数据并发送它来响应请求。然而,我对实现这一目标的最佳架构还很模糊。 TidTCPClient 和 TidTCPServer 会削减它吗?我假设客户端会在线程中请求数据,但这是否意味着服务器需要连续运行线程来响应请求?

最佳答案

TIdTCPServer 是一个多线程组件。它的客户端在它为您管理的工作线程中运行。您所要做的就是实现 OnExecute 事件来发送数据。

TIdTCPClient 不是多线程组件。它运行在您使用它的任何线程中。因此,如果您需要连续读取数据,最好运行您自己的工作线程来处理读取。 Indy 有一个封装线程的 TIdThreadComponent 组件,或者您可以手动编写自己的 TThread 代码。

100K 并不是很多数据,因此我建议完全忘记该文件并在内存中分配一个缓冲区。您的 TIdTCPServer.OnExecute 事件处理程序可以在需要时从该缓冲区读取。我什至不会费心让客户端请求数据,只需让服务器不断将最新数据推送到事件客户端即可。

尝试这样的事情:


服务器:

var
  Buffer: TIdBytes;
  Lock: TMREWSync;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
begin
  Lock.BeginRead;
  try
    AContext.Connection.IOHandler.Write(Buffer);
  finally
    Lock.EndRead;
  end;
  Sleep(1000);
end;

procedure TForm1.UpdateBuffer;
begin
  Lock.BeginWrite;
  try
    // update the Buffer content as needed...
  finally
    Lock.EndWrite;
  end;
end;

initialization
  Lock := TMREWSync.Create;
  SetLength(Buffer, 1024 * 100);
finalization
  SetLength(Buffer, 0);
  Lock.Free;

客户:

procedure TForm1.IdThreadComponent1Run(Sender: TIdThreadComponent);
var
  Buffer: TIdBytes;
begin
  IdTCPClient1.IOHandler.ReadBytes(Buffer, 1024 * 100);
  // use Buffer as needed...
end;

procedure TForm1.Connect;
begin
  IdTCPClient1.Connect;
  try
    IdThreadComponent1.Start;
  except
    IdTCPClient1.Disconnect;
    raise;
  end;
end;

procedure TForm1.Disconnect;
begin
  IdTCPClient1.Disconnect;
  IdThreadComponent1.Stop;
end;

关于Delphi 2007,Indy 10 - 用于单向传输数据 block 的最简单的 TCP/IP 设置是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29091238/

相关文章:

linux - 随机端口发起TCP请求

go - SSH 未知 TTY 错误消息

c# - 跟踪 TCP 上已连接客户端的最佳方法是什么?

android - 在本地网络上使用 TCP 还是 UDP 进行视频流传输?

delphi - Delphi中有没有办法根据不同的结果类型重载函数?

android - 无法设置动态部分大小 : Memory exhausted

c++ - Delphi:使用调试器调用 C dll 函数需要 15 秒,没有调试器需要 0.16 秒。为什么?

delphi - 如何暂停程序执行直到按下按钮?

sockets - TCP server socket编程为什么要得到两个文件描述符?

c - TCP/IP发送数据和接收数据顺序