Recent

Author Topic: fcl-net ssockets client in non-blocking mode  (Read 3227 times)

kveroneau

  • Full Member
  • ***
  • Posts: 119
fcl-net ssockets client in non-blocking mode
« on: January 10, 2017, 12:32:17 am »
Hello, while looking through the classes in fcl-net's ssockets unit, I noticed that the server class provides a method to enable non-blocking mode, however the client class TINetSocket does not.  I am not sure why this was not included, as having a non-blocking client socket can be very useful when working with custom protocols where either the client or the remote server can initiate a message at any time.  A very useful use of a non-blocking TCP socket on the client-side is to use it within a thread where you have s.Read(buf,1024) in a loop to constantly check for data from the server-side and act upon it in near real-time.  An example event loop within a thread in a GUI application might look like this:

Code: [Select]
While running do
begin
  l:=s.Read(buf,1024);
  if l > 0 then processData(buf);
  if Length(sendBuf) > 0 then sendBuffer;
end;

The sendBuf can be written to from outside of the thread using locks to allow other parts of the application to queue data out to the socket.  A better solution is to use select, poll, or epoll in a proper event loop.  However, I have yet to figure out how to implement a proper select event loop for sockets in FreePascal/Lazarus.  I can see the fpAsync unit, but I am unable to see any examples on it's use.  This example above will take much more CPU than a proper select event loop.

It is possible to use non-blocking with a client socket by using this code here:  FpFcntl(s.Handle, F_SetFl, O_NONBLOCK);

In this example, s is a class instance of TInetSocket.  This works and enables the client-side socket in non-blocking mode.  When no data is available from the socket s.Read happily returns -1 as expected.  It seems that fpSock provides access to this ability, but it is not well documented or I am just unable to locate the documentation for it.  It also seems that fpSock/fpAsync might be UNIX/Linux only, although both OS X and Windows also provide a select/poll like API for sockets as well.

I guess my other option to this would be to have the server constantly send a ping packet to each connected client so the s.Read returns and the thread code can continue processing and sending any data out to the server.  I guess I am just more used to event-based network programming where blocking sockets don't exist.

Does the Synapse Lazarus components both offer RAW TCP connections, and the ability to attach events such as connected, disconnected, dataWaiting, etc... ?

 

TinyPortal © 2005-2018