Each datagram that you send on a UDP socket is sent "by itself". It's not a part of a larger conversation. There is no 'connection' to make, since there isn't a continuous stream of data. It's "one message at a time."
Therefore, a sending program must send a destination address and port with each and every datagram that gets sent. The send() API doesn't give us a place to put an address or port, so a new API is necessary, sendto().
The sendto() API is found in the IBM manuals at this location: http://publib.boulder.ibm.com/pubs/html/as400/v4r5/ic2924/info/apis/sendto.htm
It tells us that the C-language prototype for sendto() looks like this:
int sendto(int socket_descriptor,
char *buffer,
int buffer_length,
int flags,
struct sockaddr *destination_address,
int address_length);
Nothing terribly different or exciting about this prototype. A procedure called 'sendto', with 6 parameters. An integer, a pointer, an integer, another integer, a pointer and finally an integer. So, lets prototype this in RPG:
D sendto PR 10I 0 ExtProc('sendto')
D sock_desc 10I 0 Value
D buffer * Value
D buffer_len 10I 0 Value
D flags 10I 0 Value
D destaddr * Value
D addrlen 10I 0 Value
The first four parms are identical to those used in the send() API. The only difference is that we've added a sockaddr structure to contain the address & port number of the destination. And, like every other address structure we've done, we'll need to supply a length for it.
Please, add this little gem to your SOCKET_H member.
The sendto() API is called like this:
c eval len = %size(sockaddr_in)
c alloc len toaddr
c eval p_sockaddr = toaddr
c eval sin_family = AF_INET
c eval sin_addr = SOME_IP
c eval sin_port = SOME_PORT
c eval sin_zero = *ALLx'00'
c if sendto(s: %addr(buf): buflen: 0:
c toaddr: len) < 0
C*** error! check errno!
c endif