The following example is a simple server script. It creates a server socket that listens for connections on port number 20248. It allows only one client at a time to connect. When a client connects, the server script sends the string Hello world! to the client, and then waits for the client to send back the string Hi!. Then, the server hangs up.
/* Initialization. */
OPTIONS "C_CALL"
LIBRARY rexxsock
/* Set the desired port number we want for our socket, and
* indicate what our IP address is. We must store this information
* in a stem variable, and then we will pass the name of this stem
* variable to SockSocket. SockSocket will retrieve this information
* and create a server socket. We can use any stem variable name we
* wish. Here we use "server.!", but we must set two tails, named
* port and addr. We have decided to use a port number of 20248. As
* for the IP address, if we set the port tail to the string
* "INADDR_ANY", then SockSocket will automatically lookup this
* computer's primary IP address for us.
*/
server.!addr = 'INADDR_ANY' /* Let RexxSock look up this computer's IP address */
server.!port = 20248 /* This is the port we use to communicate. The client must use the same port # */
/* Get a server socket using the above port/address. Set it into
* "listening for connections" mode, and allow only 1 client to wait
* for us to SockAccept it. If more than one client tries to connect
* simultaneously, RexxSock will automatically reject all but the
* first client.
*/
server = SockSocket(, , , 'server.!', 1)
SAY 'Server socket created and waiting for a client to connect...'
/* SockAccept will wait for and accept an incoming client connection
* and return that client's socket. Here we store that socket in
* a variable named "client". We also pass the name of a stem
* variable to SockAccept, and SockAccept fills in that stem's
* addr with the IP address of the client we connect to. You
* can use any stem variable name you desire. Here we use "client.!".
*/
client = SockAccept(server, 'client.!')
/* We got a client connected. Display its IP address. */
SAY 'Client connected from address' client.!addr
/* Send "Hello World!" to that client. Note that we
* pass the client socket to SockSend (not our server socket).
*/
SockSend(client, 'Hello world!')
/* Wait for the client to reply with its "Hi!". We omit the
* timeout arg, so we wait forever. If we pass the timeout arg,
* SockSelect will raise the USER condition for a time out. We
* need to first fill in a stem variable where the tail 0 tells how
* many sockets to wait for (ie, 1 here), and then the remaining
* tails are those sockets. We must pass that stem name as the
* first arg to SockSelect. Here, we use a stem variable named
* "reads.", but you could use any name you like. Note that we
* store the client socket in it.
*/
reads.0 = 1
reads.1 = client
timedout = SockSelect('reads.')
/* Read upto the next 250 bytes of data from the client. SockRecv
* returns the number of bytes actually read, and stuffs those bytes
* into some variable of our choice. Here, we use a variable named
* "chunk", and pass that name to SockRecv. SockRecv will raise
* USER condition if the socket has been shutdown/closed by the
* client, or if some other error occurs.
*/
bytes = SockRecv(client, 'chunk', 250)
/* Display what we received. */
SAY chunk
/* Close the socket. RexxSock will tell the client we're closing
* the connection.
*/
SockClose(socket, 1)
SAY 'Socket closed'
/* At this point we could loop around to SockAccept to wait for
* another client to connect, instead of terminating.
*/
RETURN
/* ==========================================================
* We told RexxSock to raise the USER 10 condition if there is
* ever any error (other than a SYNTAX error). We CATCH USER
* 10 here, so REXX will jump here if it is raised. So, if
* we're here, then some RexxSock function has had an error.
*
* CONDITION('D') reports the name of the RexxSock function that
* had the error. SIGL is the line number in our script where
* we had the error. The variable named "SockErrNo" is set to an
* RexxSock Error name such as "EINPROGRESS" or "ENETDOWN" etc.
* We can pass this variable to the RexxSock function SockErrMsg
* to get an appropriate error message or call SockPSock_Errno
* to display a message box.
*/
CATCH USER 10
SockPSock_Errno()
/* If you wish your server script to continue executing, instead
* of aborting, then here you would examine "SockErrNo", and
* do some handling based upon it. Then, you would SIGNAL
* back to some safe place in the script, such as going
* back to SockSelect() to wait for something more to
* happen.
*/
RETURN
CATCH SYNTAX
CONDITION('M')
RETURN