[英]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.