Just as the sendto() API adds an address and port to the send() API, so does the recvfrom() API add an address and port to the recv() API.
Sometimes in a TCP socket, you don't bother to keep track of where the connection comes from. You don't need to. You don't care. With TCP, the API takes care of making sure your responses get where they need to go.
This is not true with UDP. Each datagram stands alone. You need to read in the address that a datagram came from so that you know who to respond to -- that is, if your application requires responses at all.
So, when you supply an address and length in the recvfrom API, it's to receive the address and port that the datagram originated with. You can use it to reply!
The IBM manual page for the recvfrom() API is found right about here: http://publib.boulder.ibm.com/pubs/html/as400/v4r5/ic2924/info/apis/recvfr.htm
And it tells us that the C-language prototype for the recvfrom() API looks like this:
int recvfrom(int socket_descriptor, char *buffer, int buffer_length, int flags, struct sockaddr *from_address, int *address_length);
Yes, it's just like recv(), except that they've added a socket address structure, and an address length. You'll see that the address length is passed by pointer -- this is because the length depends on what the sending program sends us, just like it did with the accept() API.
The RPG version of recvfrom() looks like this:
D recvfrom PR 10I 0 ExtProc('recvfrom') D sock_desc 10I 0 Value D buffer * Value D buffer_len 10I 0 Value D flags 10I 0 Value D fromaddr * Value D addrlength 10I 0
You'll note that we're passing the address length parameter 'by address' instead of passing a pointer to an integer. This looks exactly the same to the API that receives the parameter, but allows the compiler to do some better validity checking.
Add this to your SOCKET_H member, please.
Here's how we call recvfrom:
C eval datalen = recvfrom(s: %addr(buf): c %size(buf): 0: fromaddr: fromlen) c if datalen < 0 c*** Error occurred, check errno! c endif