[英]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只能在該線程上下文中使用。
在這種情況下,您應該:
為每個客戶端提供自己的ADO連接和查詢對象。 您可以:
A.在OnConnect
事件中創建它們,並將它們存儲在TIdContext
以在OnExecute
事件中使用,然后在OnDisconnect
事件中釋放它們。 或者只是根據需要在OnExecute
事件中創建並釋放它們。
B.從TIdThreadWithTask
派生一個新類,並覆蓋其虛擬的BeforeExecute()
和AfterExecute()
方法來創建和釋放ADO對象,然后將TIdSchedulerOfThread...
組件之一分配給TIdTCPServer.Scheduler
屬性並分配您的線程類到TIdSchedulerOfThread.ThreadClass
屬性。 然后,在服務器事件中,可以使用TMyThreadClass(TIdYarnOfThread(TIdContext.Yarn).Thread)
訪問調用線程的ADO對象。
創建一個單獨的ADO對象池。 當客戶端需要訪問數據庫時,讓其將適當的ADO對象編組到調用線程的上下文中,然后在完成時將這些對象放回池中。
無論哪種方式,由於ADO都是基於COM的,所以請不要忘記在OnConnect
和OnDisconnect
事件或TIdThreadWithTask.BeforeExecute()
中為需要訪問ADO對象的每個客戶端線程調用CoInitialize/Ex()
和CoUnintialize()
。 TIdThreadWithTask.BeforeExecute()
和TIdThreadWithTask.AfterExecute()
方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.