繁体   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