rexx-things/samples/oorexx/sfserver.rex
2025-03-12 20:50:48 +00:00

97 lines
2.7 KiB
Rexx
Executable File

#!/usr/bin/env rex
/*----------------------------------------------------------------------------*/
/* Simple socket server using socket function package */
srv = .myserver~new()
srv~listen()
exit
/* Rexx */
::class myserver
::method init
expose socket shutdown
socket = socksocket('AF_INET', 'SOCK_STREAM', '0')
shutdown = .false
::method monitor unguarded
expose socket 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
/* create a socket (to connect to ourselves) */
socket = socksocket('AF_INET', 'SOCK_STREAM', 'IPPROTO_TCP')
/* specify the host we will connect to */
host.!family = 'AF_INET'
host.!addr = '127.0.0.1'
host.!port = '50010'
/* connect to the server (if it hasn't already shutdown) */
if sockconnect(socket, 'host.!') < 0 then
/* close the socket connection */
call sockclose socket
::method listen
expose socket shutdown
/* specify the host we will run as */
host.!family = 'AF_INET' -- Protocol family (only AF_INET is supported)
host.!addr = '127.0.0.1' -- localhost IP address
host.!port = '50010' -- Port number
/* bind to the host information */
call SockSetSockOpt socket, 'SOL_SOCKET', 'SO_REUSEADDR', 1
if sockbind(socket, 'host.!') < 0 then do
say 'SockBind failed:' errno
exit
end
/* start listening for new connections */
if socklisten(socket, 256) < 0 then do
say 'SockListen failed:' errno
exit
end
say "Server listening at" host.!addr':'host.!port
self~start('monitor') -- this will allow the server to be shutdown cleanly
do forever
cs = sockaccept(socket) -- prepare to accept a new client
if cs = -1 | shutdown then leave -- if the socket is closed (by monitor) sockaccept will fail
/* this will spawn a thread to handle the new client and then return to accept the next client */
self~start('respond', cs)
end
if cs <> -1 then
if sockclose(cs) < 0 then
say 'SockClose failed:' errno
if sockclose(socket) < 0 then
say 'SockClose failed:' errno
::method respond unguarded
use arg socket
do forever
/* get data from the client */
if sockrecv(socket, 'data', 1024) < 1 then leave
/* echo that data back to the client */
say data
call socksend socket, 'Echo:' data
end
::requires 'rxsock' LIBRARY