#!/usr/bin/env rexx srv = .myserver~new() srv~listen() Exit /* This is technically the end of the rexx script, in the classical sense. Everything after the exit statement above will get parsed by the object generator on the first pass over the script, not the rexx interpreter. Then, the rexx interpreter will use the generated objects when it interprets the script on the second-pass, to execute the instructions. */ ::requires 'socket.cls' ::class myserver ::method init expose sock shutdown /* instantiate an instance of the socket class */ sock = .socket~new() shutdown = .false ::method monitor unguarded expose sock shutdown /* this seems to be the only cross platform way of cleanly shutting down. this may not be the best method of shutting down, but does work on both Linux and Windows */ say 'Press [Enter] To Shutdown' pull seconds if seconds~dataType("n") then do say "shutdown in" seconds "sec" call SysSleep seconds end shutdown = .true /* instantiate an instance of the socket class */ sock = .socket~new() host = .inetaddress~new('localhost', '50010') /* connect to the server (if it hasn't already shutdown) */ if sock~connect(host) < 0 then /* close the socket connection */ sock~close() ::method listen expose sock shutdown /* instantiate an instance of the inetaddress class with the host information of the server we will contact: localhost and port 50010 */ host = .inetaddress~new('localhost', '50010') /* bind to the host information */ sock~setOption('SO_REUSEADDR', 1) if sock~bind(host) < 0 then do say 'Bind failed:' sock~errno exit end if sock~listen(256) < 0 then do say 'Listen failed:' sock~errno exit end say "Server listening at" host~address':'host~port self~start('monitor') -- this will allow the server to be shutdown cleanly do forever csock = sock~accept() -- prepare to accept a new client if .nil = csock | shutdown then leave -- if the socket has closed or the shutdown flag is set /* this will spawn a thread to handle the new client and then return to accept the next client */ self~start('respond', csock) end if csock~isa(.socket) then if csock~close() < 0 then say 'SockClose failed:' sock~errno if sock~close() < 0 then say 'SockClose failed:' sock~errno ::method respond unguarded use arg sock do forever /* get data from the client */ data = sock~recv(1024) if data = .nil | data == "" then leave say time data /* echo that data back to the client */ sock~send('Echo:' data) end