FORTH Echo Server Revisited

2015-12-29 03:32:00 UTC

GForth comes with a special library called unix/socket.fs for dealing with TCP socket connections. Unfortunatly, there is (as far as I know) no formal documentation on using socket.fs aside from reading the source code. If you’re a FORTH novice like me that isn’t much help.

The best thing I could find was an example TCP echo server on Rosetta Code. You can try it out for yourself by:

  1. Copy the code into a local file.
  2. Execute the file via gforth FILENAME
  3. Connect to the echo server using telnet (telnet localhost 12321).
  4. Send it messages via telnet, seperated by a carriage return.

I decided to factor down the code some more and add additional comments:


\ Pull in the library
include unix/socket.fs

\ Set some defaults
128 constant buffer-size
4 constant maximum-connections-allowed

: 3drop
  drop drop drop ;

: read-the-buffer
  2dup 2dup buffer-size read-socket nip
  dup 0> ;

: print-the-data
    ."  got: " 2dup type ;

: echo-back
    rot write-socket ;

: (echo) ( sock buf-- sock buffer )
  begin
    read-the-buffer
  while
    print-the-data
    echo-back
  repeat
  3drop ;

create buffer buffer-size allot

\ This is the main loop. It expects the TCP port number
\ to be  on the  stack when called (12321 in this case).
: echo-server ( port -- )
  \ Call 'create-server', passing in the desired port
  \ number on top of stack.
  create-server
  \ ^ Socket id is now on top of stack...
  \ .. after that, set the socket ID to listen with a
  \ max backlog of 4 connections.
  dup maximum-connections-allowed listen
  begin
    \ This word will block the thread and listen to the socket.
    dup accept-socket
    cr ." Someone just connected to the socket! " cr
    \ Push the buffer on the stack...
    buffer
    \ ...then grab the execution token for (echo)
    ['] (echo)
    \ Execute the XT for `(echo)` and push the
    \ exception onto the stack (or 0 if OK)
    catch
    cr ." Disconnected with status code " .
    drop close-socket
  again ;

12321 echo-server

Notes