【问题标题】:Indy Server and AdoQuery are conflictingIndy Server 和 AdoQuery 冲突
【发布时间】:2014-06-19 14:38:07
【问题描述】:

我有两个程序,一个是客户端,另一个是客户端的服务器。 客户端像这样向服务器发送一些数据,然后读取响应:

 idtcpclient1.WriteLn(command); //Command contains data that the server needs eg. name and surname
 progressbar1.StepIt;
 sresult := idtcpclient1.ReadLn();

服务器然后读取该行,对其进行操作并创建一个 SQL 查询。

adoquery1.Close;
adoquery1.SQL.Text := 'select * from '+sGrade;
adoquery1.Open;

但是一旦打开与数据库的连接,客户端就会给出错误“连接正常关闭”

我已经通过模拟输入在没有客户端的情况下测试了服务器代码,它工作正常。

我认为 Indy 和 AdoQuery 存在冲突 如果是这样,为什么以及如何解决它

如果不是,那是什么问题,我应该如何解决?

【问题讨论】:

  • 在使用 Indy 时,您使用哪个端口与服务器通信?
  • 问题是Indy服务端代码是在主线程之外的线程中执行的。您需要在 indy 线程的上下文中创建连接/查询。或者使用 Synchronize 在主线程的上下文中执行 DB 代码。
  • 我正在使用端口:55555
  • @whosrdaddy 我不知道如何使用“同步”,请您详细说明如何使用

标签: sql delphi delphi-7 indy tadoquery


【解决方案1】:

ADO 使用与创建它们的线程有关联的单元线程 COM 对象。除非经过编组,否则它们不能跨线程边界使用。

Indy 的 TCP 服务器是多线程的。每个客户端都在自己的线程中运行。

线程必须先调用CoInitialize/Ex() 建立与COM 的关系,然后才能访问任何COM 对象,并在使用COM 完成后调用CoUninitialize()

您的服务器失败,因为它引发了一个未捕获的异常,导致客户端断开连接。很可能是因为您没有初始化 COM。

您需要基于每个客户端创建 ADO 对象,不要在主线程中使用它们。在服务器的OnConnect 事件中,调用CoInitialize/Ex()。在OnDisconnect 事件中,调用CoUninitialize()。在OnExecute事件中,根据需要动态创建和使用新的ADO对象。

这确实意味着每个客户端都需要自己的数据库连接。如果您不希望这样,则将您的 ADO 逻辑移动到专用线程,客户端可以在需要时将请求发布到该线程。远离在主线程中做数据库工作,它不属于那里。

【讨论】:

    【解决方案2】:

    如果您使用数据模块:您可以为每个客户端创建一个数据模块实例,以避免线程错误。 Indy 可以在上下文中保存对客户端数据模块的引用。或者使用数据模块实例池,具体取决于可用资源和流量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-07
      • 1970-01-01
      相关资源
      最近更新 更多