0

我正在创建一个客户端服务器应用程序来连续流式传输图像,以像视频流式传输应用程序一样工作。

客户端应用程序有一个计时器,每 300 毫秒计时一次,以向服务器发送请求,服务器回复图像。

实现工作正常,但一段时间后(〜5分钟或更长时间后)两个应用程序都冻结而没有任何错误消息(但我很少收到消息说系统资源不足)

之前情况更糟(大约 15 秒后冻结),但我改变了idtcpserver1.terminatewaittime to 10 (from 5000 defalt) 现在它发生在 5 分钟后。

我不明白为什么会发生错误,但我很确定使用基于计时器的请求并不好。

我可以将 tcpserver 转换为不可靠的无连接协议以使其更快并减少请求压力。

但我不想使用 UDP,因为它无法检测到损坏错误(但我不需要更正,我只想知道是否有任何错误(忽略整个图像))

procedure server.IdTCPServer1Execute(AContext: TIdContext);
begin
LLine := AContext.Connection.IOHandler.ReadLn();
AContext.Connection.IOHandler.Write(ast, 0, true);
end;

procedure client.timertick(Sender: TObject);
begin
IdTCPClient1.IOHandler.WriteLn(Edit1.Text);
LLine := TMemoryStream.Create;
IdTCPClient1.IOHandler.ReadStream(LLine, -1, false);
end;

仅提供与 Indy 相关的源代码,其他源代码被保留

=============== 在 Remy Lebeau 之后更新 - TeamB 和 Arnaud Bouchez 回答 ===========

感谢冻结是由于在某些情况下无法访问图像造成的。他们提到的工具帮助我找到了问题

但是主要问题还是没有解决

我可以将 tcpserver 转换为不可靠的无连接协议以使其更快并减少请求压力。

4

2 回答 2

4

timertick您显示为内存泄漏的代码。您没有释放TMemoryStream您创建的内容,这反过来又会泄漏流在内部分配的任何内存。

TerminateWaitTimeout属性对连接的运行时行为没有影响。它仅在关闭服务器时使用,以指定服务器等待活动连接终止的时间。

TCP 不太适合流媒体,使用命令/响应来抓取图像本身就很慢。至少摆脱帧之间的命令,只要它们可用就发送帧。TCP 可以处理。然而,大多数音频/视频流应用程序都基于 UDP,以避免 TCP 使用的不必要的开销。

于 2011-11-26T00:14:48.443 回答
3

您有资源泄漏。

也许您没有释放您的网络资源或 GDI 资源。

  • 首先是运行ProcessExplorer,然后查看您的应用程序创建了多少句柄,以及创建了多少个连接;
  • 然后以内存泄漏检测模式启动 FastMM4 ;
  • 如果您的资源没有与 Delphi 类映射,请尝试在您的代码中查找它们是如何分配/释放的(使用带有 API 调用名称的 Find IDE 命令);
  • 它可能与线程问题有关——可能是某种竞争条件——尝试锁定您的共享资源;
  • 使用日志机制来跟踪进程中发生的事情,尤其是所有 Indy 类;
  • 请参阅此StackOverflow 答案中的其他提示。

UDP 的有趣之处在于您可以一次将您的流广播到多个目标。在客户端数量增加的情况下,潜在的数据包丢失通过减少带宽使用来平衡。如果您需要资源使用有限的本地广播(但在 Internet 上会更复杂),那么值得研究这个方向。

于 2011-11-25T13:01:47.163 回答