Question

I am using the Gnat Sockets package. I have a server-side socket that has been created & initialised with the following:

   GNAT.Sockets.Create_Socket(...);

...

   GNAT.Sockets.Set_Socket_Option
     (Socket => Server,
      Option => (Name => GNAT.Sockets.Receive_Timeout,
                 Timeout => Listner_Timeout));

...

   GNAT.Sockets.Listen_Socket(...);
   GNAT.Sockets.Accept_Socket(...);

All well and good sofar, but when it is time to use :

   GNAT.Sockets.Receive_Socket(...);

I have no idea how to detect if my socket has timed out, or read some data when it returns. Do I need to use the Check_Selector method (It seems a bit heavy for this use, and if so does this interact with the time out set in the Set_Socket_Option call)?

Thanks,

Was it helpful?

Solution

In any case, the Timeout parameter on Check_Selector does what it sounds like you want. You invoke Check_Selector(), and when it returns look at the status. If the Status is Complete, you've gotten "activity" such as data (assuming you're reading) or the other end of a socket closed, if Expired the selector timed out, and if Aborted then the selector was commanded to prematurely terminate via Abort_Selector().

I typically put the socket reading, including the Check_Selector() invocation, in a task so as not to block the rest of the app, and allow for an externally initiated Abort_Selector. In fact, I rarely use a timeout, I just loop the Check/Read on the socket, and when I no longer need to read the socket, like when shutting down, just call Abort_Selector() to finish it off.

OTHER TIPS

I think I read about someone using asynchronous select to handle the timeout case... something like:

loop
  select
    -- HANDLE SOCKET RECEPTION
   or
    delay 7.0; -- Wait seven seconds to timeout.
  end select;
end loop;

Note: The above is from memory, it is NOT syntax-checked or compiled.

By reading the Gnat.Sockets package spec (btw, the one you linked to does not support Receive_Timeout), my guess is Socket_Error is raised, that resolves (with Resolve_Exception) to Connection_Timed_Out.

Another possibility is that Receive_Socket returns with Last set to Item'First - 1, as if the socket was closed by peer.

I haven't tried this, but it looks as though you should get a Socket_Error exception with, maybe, EWOULDBLOCK.

This might not work too well if the data is merely trickling through, since the timeout is going to be reset every time some data arrives.

Update: I tried this on Mac OS X, and got GNAT.SOCKETS.SOCKET_ERROR: [35] Resource temporarily unavailable. [35] is EAGAIN or EWOULDBLOCK (Darwin uses the same value for both, so GNAT.Sockets deliberately makes the ambiguous report).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top