Jump to content
Clément

Listen to UDP in a TThread (Windows Service)

Recommended Posts

Hi,

I using D10.4.2 and ICS 8.65. I need to write a small UDP windows service.
 

I'm using 2 x TWSocket . One is created at the very begining and set to listening. The other is created at runtime when required and the data is sent and destroyed.

When I start the service:
Netstat reports UDP 0.0.0.0 9000 listening.
Wireshark reports data is sent and received.

When data is received some processing is done and a file must be created.


The device is returning data, as reported by wireshark too.. but DataAvailable event is not fired.
If i build the very same project in a form it all just works. But it must run as a service.

 

This is the Thread.Execute code:
 

procedure TdhsDiscoverThread.Execute;
var
  lMsg : TMsg;
begin
  fdhsDiscover := TdhsDiscover.Create(nil);
  try
    fdhsDiscover.MultiThreaded := True;
    fdhsDiscover.SetConnectionSettings(fPort,fIdentification,fIsServer);
    fdhsDiscover.SetNotificationType(fNotificationType,fBaseMessage,fNotificationHandle);
    fdhsDiscover.ListenStart;
    while GetMessage(lMsg,0,0,0) do begin
       if lMsg.message = _UM_Discover+fBaseMessage then begin
          case lMsg.lParam of
              _UP_DISCOVER_PARAM_ServerSettings :
                    fdhsDiscover.FindServer;
          end;
       end;

    end;
    fdhsDiscover.ListenStop;

  finally
    fdhsDiscover.Free;
  end;

end;

netstat is reporting:

  UDP    0.0.0.0:9000           *:*

 

Any ideas?

Share this post


Link to post

Your message loop is not dispatching any system messages it receives.  For example, asynchronous socket messages (since ICS uses non-blocking sockets).  You need to call DispatchMessage() for any messages that you do not process on your own, eg:

while GetMessage(lMsg,0,0,0) do begin
  if lMsg.message = _UM_Discover+fBaseMessage then begin
    if lMsg.lParam = _UP_DISCOVER_PARAM_ServerSettings then begin
      fdhsDiscover.FindServer;
    end;
  end else
  begin
    TranslateMessage(lMsg);
    DispatchMessage(lMsg);
  end;
end;

 

Edited by Remy Lebeau

Share this post


Link to post
46 minutes ago, Remy Lebeau said:

else begin TranslateMessage(lMsg); DispatchMessage(lMsg); end;

Btw, TranslateMessage only deals with virtual keys so is useless for worker threads. Removing it allows to save 3 lines 😉

  • Like 1

Share this post


Link to post
1 hour ago, Fr0sT.Brutal said:

Btw, TranslateMessage only deals with virtual keys so is useless for worker threads.

That depends on what the thread actually does.  Worker threads can have UIs and process user input, too.  But, being that this code is running in a service, that is not likely to happen.  So, if the thread has no UI, no keyboard input processing, then certainly TranslateMessage() can be omitted.  But it doesn't really hurt to leave it in, either.  It would essentially just be a no-op.

Edited by Remy Lebeau

Share this post


Link to post

TWSocket also implements this, you can call it by WSocket1.MessagePump.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×