Ever wanted a normal (blocking) socket connection to listen for data but also wanted to check for a condition if it should stop listening?
Problem is that the default BSD 4.3 version of the socket API (which is the default API to bind to) does not support setting timeouts. Trying to set a timeout for receiving data results in
3021 : The value specified for the argument is not correct.
But by switching to the BSD 4.4 / Unix98) version of the socket API you can set
timeouts with the
How to do it
The timeout can be set directly after the
connect() call. It is set by calling
setsockopt() function with the corresponding parameters.
- Socket descriptor
- SOL_SOCKET for stating that it will be a socket option
- SO_RCVTIMEO for changing the timeout for receiving data
- timeout value
- timeout value length
The prototype looks Like this:
dcl-pr setsockopt int(10) extproc('qso_setsockopt98'); socket int(10) value; level int(10) value; option_name int(10) value; option_value pointer value; option_length int(10) value; end-pr;
The timeout is passed as a data structure containing seconds and microseconds for the timeout value.
dcl-ds timeout_t qualified template; seconds int(10); useconds int(10); end-ds;
The call may look something like this:
if (setsockopt(socket : SOL_SOCKET: SO_RCVTIMEO : %addr(timeout) : %size(timeout)) = -1); errPtr = errno(); message_sendEscapeMessageToCaller( 'Could not set socket timeout. ' + %char(c_err) + ': ' + %str(strerror(c_err))); endif;
The socket functions are contained in the service programs
contained modules and functions can be displayed with
The BSD 4.3 and 4.4 versions of the Socket API are contained in this service program. The BSD 4.4 version (which is also identical to the Unix98 version) is prefixed with qso_ and suffixed with 98.
So the program can be created in the usual way and be bound to the same service program. The names in the prototypes are important as they decide which functions are called.
For a working example take a look at the STOMP client, source file stomp.rpgle, procedure stomp_open.
Have a nice break.