For the sake of the original post regarding the lnet and the handles, If someone can make an example without using classes, it would be welcome, for I know that you can write things with many different ways.
Like it was already said... you can't use lnet without classes.
But I'm curious. You say you want asynchronous communication... Do you know what that means?
Now you have a program with just one flow. Line by Line. You can't achieve asynchrony that way.
Asynchronous programming is a form of parallel programming that allows a unit of work to run separately from the primary application thread. When the work is complete, it notifies the main thread (as well as whether the work was completed or failed). There are numerous benefits to using it, such as improved application performance and enhanced responsiveness.
https://stackify.com/when-to-use-asynchronous-programmingSo if you want to do asynchronous communication, you need to do some form of multiple program flow.
Coming back to your original lnet server (receiver).
Because lnet is event driven you DO need to signal it to do it's work in the background (well not actually background but you need to let it do it's work). You can do that with just one line. Sock.CallAction. So if you add line 13 to your original program, it will work.
(Note that this isn't real asynchronous communication though. You're just misusing the library to force synchronous communications.)
program test1;
{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
{$APPTYPE CONSOLE}
uses
SysUtils, crt, lnet, lnetbase;
var
Sock: TLUDP;
tmp: string;
begin
Sock := TLUdp.Create(nil);
Sock.listen(1234);
repeat
Sock.CallAction;
if Sock.GetMessage(tmp) > 0 then
writeln(tmp);
sleep(100);
until False;
end.
Bare in mind... this is not the actual correct way to do things. You are still trying to do a GetMessage while there might not even be a message on the line. This could block the CallAction again and I'm not sure the code will work correctly. The correct way would be to use the sock.OnReceive because then you know there is a message to receive.
Did you look at the example ludp.pp in \config\onlinepackagemanager\packages\lnet\examples\console\ludp ??
It has a complete server/client udp example with a TLUDPTest class.
So the correct way to do it would be something like this:
program test1;
{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
{$APPTYPE CONSOLE}
uses
SysUtils, crt, lnet, lnetbase;
var
Sock: TLUDP;
tmp: string;
type
TMyDummy = class
class procedure OnReceive(aSocket: TLSocket);
end;
class procedure TMyDummy.OnReceive(aSocket: TLSocket);
begin
if Sock.GetMessage(tmp) > 0 then
writeln(tmp);
end;
begin
Sock := TLUdp.Create(nil);
Sock.OnReceive := TMyDummy.OnReceive;
Sock.listen(1234);
repeat
Sock.CallAction;
sleep(100);
until False;
end.
You see, now when there is no message, CallAction keeps getting called. When there is a message the OnReceive from TMyDummy is called and the message is read and printed. In the example ludp.pp you see you can also send a reply back.
(The TMyDummy can be called something else of course, this is just to show you can use classes, and class procedures, without creating an instance. But that might be something too advanced for now
)