簡體   English   中英

Indy TCP Server凍結,不知道為什么

[英]Indy TCP Server Freezes, no idea why

我有一個服務器和一個客戶端(Delphi)。

客戶端獲取登錄詳細信息,然后連接到服務器,將其發送到要驗證的服務器,服務器接收到的數據經過驗證,然后返回給定的數據是否正確。

如果數據正確,則客戶端將繼續到下一個窗口,在該窗口中,他們將一些數據輸入相應的字段中,然后將數據發送到服務器,當服務器接收到數據時,它將存儲該數據,然后回復客戶端,表明已成功存儲了該數據。 當通知客戶端數據已成功存儲時,它將顯示一條消息,通知用戶,然后終止。

在測試時,客戶端運行在四台不同的計算機上(每台計算機將打開和關閉客戶端大約6次),服務器突然停止回復客戶端(客戶端顯示消息,提示“連接已正常關閉”)

這是服務器返回的錯誤: 這是服務器返回的錯誤
因此,錯誤似乎出在ADOQuery打開連接以執行SQL時,為什么僅在執行30次后才引起異常?

關於我的問題的任何建議,因為我不知道可能是什么。 謝謝你的幫助 :)

如果客戶端收到“正常關閉連接”錯誤,則表示服務器在服務器端關閉了該客戶端的連接。 如果您的服務器代碼未明確執行此操作,則通常意味着在服務器的事件處理程序之一中引發了未捕獲的異常,這將導致服務器關閉套接字(如果該異常是在OnConnect事件之后和OnDisconnect之前引發的,事件,則在關閉套接字之前觸發OnDisconnect )。 TIdTCPServer具有一個OnException事件來報告該情況。

如果銷毀的話, TIdTCPClient關閉銷毀插座。

更新TIdTCPServer是一個多線程組件。 每個客戶端連接都在其自己的線程中運行。 ADO使用綁定到創建線程的線程的普通線程COM對象,除非使用CoMarshalInterThreadInterfaceInStream() + CoGetInterfaceAndReleaseStream()IGlobalInterfaceTable接口跨線程邊界將其編組,否則ADO只能在該線程上下文中使用。

在這種情況下,您應該:

  1. 為每個客戶端提供自己的ADO連接和查詢對象。 您可以:

    A.在OnConnect事件中創建它們,並將它們存儲在TIdContext以在OnExecute事件中使用,然后在OnDisconnect事件中釋放它們。 或者只是根據需要在OnExecute事件中創建並釋放它們。

    B.從TIdThreadWithTask派生一個新類,並覆蓋其虛擬的BeforeExecute()AfterExecute()方法來創建和釋放ADO對象,然后將TIdSchedulerOfThread...組件之一分配給TIdTCPServer.Scheduler屬性並分配您的線程類到TIdSchedulerOfThread.ThreadClass屬性。 然后,在服務器事件中,可以使用TMyThreadClass(TIdYarnOfThread(TIdContext.Yarn).Thread)訪問調用線程的ADO對象。

  2. 創建一個單獨的ADO對象池。 當客戶端需要訪問數據庫時,讓其將適當的ADO對象編組到調用線程的上下文中,然后在完成時將這些對象放回池中。

無論哪種方式,由於ADO都是基於COM的,所以請不要忘記在OnConnectOnDisconnect事件或TIdThreadWithTask.BeforeExecute()中為需要訪問ADO對象的每個客戶端線程調用CoInitialize/Ex()CoUnintialize()TIdThreadWithTask.BeforeExecute()TIdThreadWithTask.AfterExecute()方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM