2011-11-25 66 views
0

我正在創建一個客戶端服務器應用程序以連續流式傳輸圖像,以像視頻流應用程序一樣工作。在Delphi中連接較少的TCP客戶端服務器應用程序

客戶端應用程序有一個計時器,每300毫秒發送一個計時器向服務器發送請求,服務器回覆圖像。

實施工作正常,但過一段時間(約5分鐘或更長時間後)兩種版本之後獲得凍結沒有任何錯誤消息(但是非常很少,我得到一個消息,說出來的系統資源)

這之前甚至更糟糕(約15秒後凍結),但現在它發生在5分鐘後,我改變了idtcpserver1.terminatewaittime to 10 (from 5000 defalt)

我不明白爲什麼錯誤發生,但我很確定它不是很好使用基於計時器的請求。

我可以將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; 

只有源代碼相關的印地給予別人隱瞞

===============更新雷米勒博後 - TeamB和Arnaud Bouchez解答====== ====

感謝凍結是由於在某些情況下無法訪問圖像造成的。 他們提到的工具幫助我追查問題

但仍是主要問題不解決

我可以轉換的tcpserver爲不可靠的無連接的協議,使其速度更快,降低了要求的壓力。

+0

這兩個應用在進程管理器中的內存是什麼? – Graymatter

+0

凍結時的內存狀態並不差,與運行時相同(6,000 kb),但進程使用率下降到0% – VibeeshanRC

+2

根據定義,TCP不是無連接嗎? – jpfollenius

回答

4

您顯示爲內存泄漏的timertick代碼。您沒有釋放您創建的TMemoryStream,這反過來會泄漏流內部分配的任何內存。

TerminateWaitTimeout屬性對連接的運行時行爲沒有影響。它僅在關閉服務器時使用,以指定服務器等待活動連接終止的時間。

TCP不適合流媒體,並且使用命令/響應來抓取圖像的速度非常慢。至少擺脫幀間的命令,只要幀可用就發送幀。 TCP可以處理這個問題。但是,大多數音頻/視頻流應用都基於UDP,以避免TCP使用不必要的開銷。

3

您有資源泄漏。

也許你沒有釋放你的網絡資源或GDI資源。

  • 首先是運行ProcessExplorer再看看有多少處理您的應用程序創建,以及有多少個連接創建的;
  • 然後啓動FastMM4 memory leak detection mode;
  • 如果您的資源未與Delphi類映射,請嘗試在您的代碼中查找它們的分配/釋放方式(使用Find API命令和API調用名稱);
  • 它可能與線程問題有關 - 也許某種競爭條件 - 嘗試鎖定您的共享資源;
  • 使用logging mechanism來追蹤你的過程中發生的事情,特別是關於所有Indy類;
  • 查看StackOverflow answer中的其他提示。

什麼是UDP有趣的是,你可以廣播你流到多個目標的一次。在客戶數量增加的情況下,潛在分組丟失由減少的帶寬使用來平衡。值得關注的是,如果您需要有限的資源使用的本地廣播(但在互聯網上會更加複雜),這個方向是值得關注的。

+0

不,我使用FastMM4,我非常在意內存管理;請在我的問題 – VibeeshanRC

+0

+1下面看到我的評論:「這可能與線程問題有關 - 可能是某種競爭條件 - 嘗試鎖定您的共享資源;」 – VibeeshanRC

+1

@vibeeshanRC你是否在內存泄漏檢測模式下運行它?你可以有一個非常小的全局內存泄漏,不值得注意使用進程資源管理器(一些KB),但它會導致一些Windows句柄不被釋放,所以會引發錯誤。如果您確定沒有內存泄漏,則大多數Indy類可能會正確釋放,因此可能是相應的Windows資源。唯一的問題是如果實例在關閉時立即釋放(例如整個列表),而在連接完成時它應該在運行時。 –

相關問題