windows 服务中的 Indy UPDServer 未监听
Indy UPDServer in windows service not listening
我创建了一个 windows 服务,它将在服务器机器上 运行 ,并且必须监听客户端的请求以通过 UDP 向他们发送文件。我创建了客户端应用程序,现在我正在尝试向服务器发送 UDP 消息,但是 UDPRead
过程似乎没有被调用。我在windows 10中使用Delphi XE7。测试环境是:
- 客户端:表单应用程序,
TIdUDPServer
侦听端口 27905。
正确发送和接收数据。
- 服务器:Windows 服务,
TIdUDPServer
侦听端口 27906。
使用 TIdUDPServer.Send
正确发送数据,但没有收到
任何东西。
- 防火墙和防病毒软件已停用,以防万一。
- 包正在发送到 IP 127.0.0.1
我确认问题出在 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()
请求,这可以解释为什么事件处理程序从不触发。
因此,您有两个可能的选择:
定期调用服务 CheckSynchronize()
,例如在其 OnExecute
事件中。然后 OnUDPRead
事件将在服务线程的上下文中触发。
将TIdUDPServer.ThreadedEvent
属性设置为true(默认为false)。当 ThreadedEvent
为真时,UDP 工作线程绕过 Synchronize()
并直接触发 OnUDPRead
事件。因此,您只需确保您的事件处理程序在其中包含线程安全代码。
我创建了一个 windows 服务,它将在服务器机器上 运行 ,并且必须监听客户端的请求以通过 UDP 向他们发送文件。我创建了客户端应用程序,现在我正在尝试向服务器发送 UDP 消息,但是 UDPRead
过程似乎没有被调用。我在windows 10中使用Delphi XE7。测试环境是:
- 客户端:表单应用程序,
TIdUDPServer
侦听端口 27905。 正确发送和接收数据。 - 服务器:Windows 服务,
TIdUDPServer
侦听端口 27906。 使用TIdUDPServer.Send
正确发送数据,但没有收到 任何东西。 - 防火墙和防病毒软件已停用,以防万一。
- 包正在发送到 IP 127.0.0.1
我确认问题出在 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()
请求,这可以解释为什么事件处理程序从不触发。
因此,您有两个可能的选择:
定期调用服务
CheckSynchronize()
,例如在其OnExecute
事件中。然后OnUDPRead
事件将在服务线程的上下文中触发。将
TIdUDPServer.ThreadedEvent
属性设置为true(默认为false)。当ThreadedEvent
为真时,UDP 工作线程绕过Synchronize()
并直接触发OnUDPRead
事件。因此,您只需确保您的事件处理程序在其中包含线程安全代码。