windows 服务中的 Indy UPDServer 未监听

Indy UPDServer in windows service not listening

我创建了一个 windows 服务,它将在服务器机器上 运行 ,并且必须监听客户端的请求以通过 UDP 向他们发送文件。我创建了客户端应用程序,现在我正在尝试向服务器发送 UDP 消息,但是 UDPRead 过程似乎没有被调用。我在windows 10中使用Delphi XE7。测试环境是:

我确认问题出在 windows 服务,因为我在 windows 服务的主要 class 的 Create 方法中对 TIdUDPServer.Send 进行了硬编码,只是为了查看是否客户端应用程序收到它,它确实如此。此外,我已经从客户端发送UDP包到我最近开发的另一个表单应用程序,看它是否正在接收数据,并且确实如此。

我正在 windows 服务应用程序中创建 TIdUDPServer 对象,如下所示:

UDP := TIdUDPServer.Create(nil);
UDP.OnUDPRead := UDPRead;
UDP.DefaultPort := pListenPort;
UDP.Bindings.Clear;
UDP.Bindings.Add.IPVersion:=Id_IPv4;
UDP.Active := True;

程序声明为:

procedure TRed.UDPRead(AThread: TIdUDPListenerThread; const AData: TidBytes; ABinding: TIdSocketHandle);

可能我遗漏了什么,但我找不到 windows 服务中 UDPServer 失败的原因。任何线索将不胜感激,提前谢谢你。

TIdUDPServer 使用工作线程循环读取传入数据,每当新数据到达时触发 OnUDPRead 事件。

默认情况下,OnUDPRead 事件处理程序由对 TThread.Synchronize() 的调用触发,这意味着它在主 UI 线程(或至少任何线程)的上下文中触发调用 RTL 的 CheckSynchronize() 函数),而不是在 UDP 工作线程中。很可能您的服务没有处理 Synchronize() 请求,这可以解释为什么事件处理程序从不触发。

因此,您有两个可能的选择:

  1. 定期调用服务 CheckSynchronize(),例如在其 OnExecute 事件中。然后 OnUDPRead 事件将在服务线程的上下文中触发。

  2. TIdUDPServer.ThreadedEvent 属性设置为true(默认为false)。当 ThreadedEvent 为真时,UDP 工作线程绕过 Synchronize() 并直接触发 OnUDPRead 事件。因此,您只需确保您的事件处理程序在其中包含线程安全代码。