A more detailed explanation will come later. For the time being, know that you will need the copy members and service programs from Scott Klement's sockets tutorial.
*
* Example of calling the connect() API with a timeout to test
* whether or not a particular IP address or host name and port name
* or number is listening.
*
* This program requires the copy members and service programs
* used in Scott Klement's sockets tutorial. Many thanks to Scott
* for writing this, I can only take credit for adding some
* parms.
*
H DFTACTGRP(*NO) ACTGRP(*NEW)
H BNDDIR('QC2LE') BNDDIR('SOCKTUT/SOCKUTIL')
D/copy socktut/qrpglesrc,socket_h
D/copy socktut/qrpglesrc,errno_h
D/copy socktut/qrpglesrc,sockutil_h
*********************************************************
* end of IFS API call definitions
*********************************************************
D die PR
D peMsg 256A const
D cmd PR ExtPgm('QCMDEXC')
D command 200A const
D length 15P 5 const
D sock S 10I 0
D port S 5U 0
D flags S 10I 0
D host s 32A
D portname s 32A
D msg s 32A
D to_in s 10S 0
D addr s 10U 0
D connto S like(sockaddr_in)
D err S 10I 0
D connfds S like(fdset)
D timeout S like(timeval)
C*************************************************
C* The user will supply a hostname and file
C* name as parameters to our program...
C*************************************************
c *entry plist
c parm host
c parm portname
c parm to_in
c eval *inlr = *on
C*************************************************
C* For this example, we'll look up the port
C* number portname passed in:
C*************************************************
c eval p_servent = getservbyname(portname:'tcp')
c if p_servent = *NULL
c callp die('Can''t find the HTTP service!')
c return
c endif
c eval port = s_port
C*************************************************
C* Get the 32-bit network IP address for the host
C* that was supplied by the user:
C*************************************************
c eval addr = inet_addr(%trim(host))
c if addr = INADDR_NONE
c eval p_hostent = gethostbyname(%trim(host))
c if p_hostent = *NULL
c callp die('Unable to find that host!')
c return
c endif
c eval addr = h_addr
c endif
C*************************************************
C* Create a socket
C*************************************************
c eval sock = socket(AF_INET: SOCK_STREAM:
c IPPROTO_IP)
c if sock < 0
c callp die('socket(): ' + %str(strerror(errno)))
c return
c endif
c*************************************************
C* Put the socket in non-blocking mode:
c*************************************************
c eval flags = fcntl(sock: F_GETFL)
c eval flags = flags + O_NONBLOCK
c if fcntl(sock: F_SETFL: flags) < 0
c callp die('fcntl(): ' + %str(strerror(errno)))
c return
c endif
c*************************************************
C* Create a socket address structure that
C* describes the host & port we wanted to
C* connect to
C*************************************************
c eval p_sockaddr = %addr(connto)
c eval sin_family = AF_INET
c eval sin_addr = addr
c eval sin_port = port
c eval sin_zero = *ALLx'00'
C*************************************************
C* Start the connection process.
C*************************************************
c if connect(sock: %addr(connto):
c %size(connto) ) < 0
c eval err = errno
c if err <> EINPROGRESS
c callp close(sock)
c callp die('connect(): '+%str(strerror(err)))
c return
c endif
c endif
C*************************************************
C* wait up to 30 sec for connection to be made
C*************************************************
c callp FD_ZERO(connfds)
c callp FD_SET(sock: connfds)
c eval p_timeval = %addr(timeout)
c* eval tv_sec = 30
c eval tv_sec = to_in
c eval tv_usec = 0
c if select(sock+1: *NULL:
c %addr(connfds):
c *NULL:
c %addr(timeout)) < 0
c eval err = errno
c callp close(sock)
c callp die('select(): '+%str(strerror(err)))
c return
c endif
c if FD_ISSET(sock: connfds) = *OFF
c callp close(sock)
c callp die('connect(): time out value reached')
c return
c endif
C* Here we are connected. We can use send() & recv() to
C* send data here...
c callp close(sock)
c return
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* This ends this program abnormally, and sends back an escape.
* message explaining the failure.
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P die B
D die PI
D peMsg 256A const
D SndPgmMsg PR ExtPgm('QMHSNDPM')
D MessageID 7A Const
D QualMsgF 20A Const
D MsgData 256A Const
D MsgDtaLen 10I 0 Const
D MsgType 10A Const
D CallStkEnt 10A Const
D CallStkCnt 10I 0 Const
D MessageKey 4A
D ErrorCode 32766A options(*varsize)
D dsEC DS
D dsECBytesP 1 4I 0 INZ(256)
D dsECBytesA 5 8I 0 INZ(0)
D dsECMsgID 9 15
D dsECReserv 16 16
D dsECMsgDta 17 256
D wwMsgLen S 10I 0
D wwTheKey S 4A
c eval wwMsgLen = %len(%trimr(peMsg))
c if wwMsgLen<1
c return
c endif
c callp SndPgmMsg('CPF9897': 'QCPFMSG *LIBL':
c peMsg: wwMsgLen: '*ESCAPE':
c '*PGMBDY': 1: wwTheKey: dsEC)
c return
P E
/define ERRNO_LOAD_PROCEDURE
/copy socktut/qrpglesrc,errno_h