Open Source on IBM i

Hey Socket, take a break!

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 setsockopt function.

How to do it

The timeout can be set directly after the connect() call. It is set by calling the setsockopt() function with the corresponding parameters.

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;

Binding

The socket functions are contained in the service programs QSOSRV1. The contained modules and functions can be displayed with DSPSRVPGM QSOSRV1.

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.

Example

For a working example take a look at the STOMP client, source file stomp.rpgle, procedure stomp_open.

Have a nice break.

Mihael

Tags : RPG