ooRexx logo
   1: #!/usr/bin/rexx
   2: /*----------------------------------------------------------------------------*/
   3: /*                                                                            */
   4: /* Description: Simple socket server using socket class                       */
   5: /*                                                                            */
   6: /* Copyright (c) 2007-2008 Rexx Language Association. All rights reserved.    */
   7: /*                                                                            */
   8: /* This program and the accompanying materials are made available under       */
   9: /* the terms of the Common Public License v1.0 which accompanies this         */
  10: /* distribution. A copy is also available at the following address:           */
  11: /* http://www.ibm.com/developerworks/oss/CPLv1.0.htm                          */
  12: /*                                                                            */
  13: /* Redistribution and use in source and binary forms, with or                 */
  14: /* without modification, are permitted provided that the following            */
  15: /* conditions are met:                                                        */
  16: /*                                                                            */
  17: /* Redistributions of source code must retain the above copyright             */
  18: /* notice, this list of conditions and the following disclaimer.              */
  19: /* Redistributions in binary form must reproduce the above copyright          */
  20: /* notice, this list of conditions and the following disclaimer in            */
  21: /* the documentation and/or other materials provided with the distribution.   */
  22: /*                                                                            */
  23: /* Neither the name of Rexx Language Association nor the names                */
  24: /* of its contributors may be used to endorse or promote products             */
  25: /* derived from this software without specific prior written permission.      */
  26: /*                                                                            */
  27: /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS        */
  28: /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT          */
  29: /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS          */
  30: /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT   */
  31: /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,      */
  32: /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED   */
  33: /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,        */
  34: /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY     */
  35: /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING    */
  36: /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS         */
  37: /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.               */
  38: /*                                                                            */
  39: /* Author: David Ruggles                                                      */
  40: /* Adapted: Ruurd Idenburg  - 2015/03/25 - host and port as arguments         */
  41: /*                                         input echoed to STDOUT             */
  42: /*                                                                            */
  43: /*----------------------------------------------------------------------------*/
  44: parse arg hostname port
  45: if hostname=='' then hostname = 'localhost'
  46: if port=='' then port = 726578
  47: 
  48: srv = .myserver~new(hostname, port)
  49: srv~listen()
  50: 
  51: ::requires 'socket.cls'
  52: 
  53: ::class myserver
  54: 
  55: ::method init
  56:     expose sock hostname port shutdown
  57:     use strict arg hostname, port
  58: 
  59: /*  instaniate an instance of the socket class  */
  60:     sock = .socket~new()
  61: 
  62:     shutdown = .false
  63: 
  64: ::method monitor unguarded
  65:     expose sock hostname port shutdown
  66: 
  67: /*  this seems to be the only cross platform way of cleanly shutting down.
  68:     this may not be the best method of shutting down, but does work on both
  69:     Linux and Windows  */
  70:     say 'Press [Enter] To Shutdown'
  71:     pull .
  72: 
  73:     shutdown = .true
  74: 
  75: /*  instaniate an instance of the socket class  */
  76:     sock = .socket~new()
  77: 
  78:     host = .inetaddress~new(hostname, port)
  79: /*  connect to the server (if it hasn't already shutdown)  */
  80:     if sock~connect(host) < 0 then
  81:     /*  close the socket connection  */
  82:         sock~close()
  83: 
  84: ::method listen
  85:     expose sock hostname port shutdown
  86:     --trace i
  87: 
  88: /*  instaniate an instance of the inetaddress class
  89:     with the host information of the server we will
  90:     contact: localhost and port 726578
  91:     we use the "gethostid" class method of the socket
  92:     class to determine the localhost address  */
  93:     host = .inetaddress~new(hostname, port)
  94: 
  95: /*  bind to the host information  */
  96:     if sock~bind(host) < 0 then do
  97:         say 'Bind Failed'
  98:         exit
  99:     end
 100: 
 101:     if sock~listen(256) < 0 then do
 102:         say 'Listen Failed'
 103:         exit
 104:     end
 105: 
 106:     self~start('monitor')   --  this will allow the server to be shutdown cleanly
 107: 
 108:     do forever
 109:         csock = sock~accept()   --  prepare to accept a new client
 110:         if .nil = csock | shutdown then leave   --  if the socket has closed or the shutdown flag is set
 111:     /*  this will spawn a thread to handle the new client and then return to accept the next client  */
 112:         self~start('respond', csock)
 113:     end
 114:     --trace ?i
 115:     if csock~isa(.socket) then
 116:         if csock~close() < 0 then
 117:             say 'SockClose Failed'
 118: 
 119:     if sock~close() < 0 then
 120:         say 'SockClose Failed'
 121: 
 122: ::method respond unguarded
 123:     use arg sock
 124:     do forever
 125:         /*  get data from the client  */
 126:         data = sock~recv(1024)
 127:         if data = .nil | data = '' then leave
 128:         .output~lineout(data)
 129:         /*  echo that data back to the client  */
 130:         --sock~send('Echo:' data)
 131:     end
If you feel inclined to make corrections, suggestions etc., please mail me any.
All content © Ruurd Idenburg, 2007–, except where marked otherwise. All rights reserved. This page is primarily for non-commercial use only. The Idenburg website records no personal information and sets no ‘cookies’. This site is hosted on a VPS(Virtual Private System) rented from Transip.nl, a Dutch company, falling under Dutch (privacy) laws (I think).

This page updated on by Ruurd Idenburg.