[racket] sustained network

From: Danny Yoo (dyoo at hashcollision.org)
Date: Mon Apr 8 19:10:08 EDT 2013

An interesting example might be an echo-style server, where the server
reads input and writes output forever.  Here's what it can look like:

---------------------------------------------------------------

#lang racket/base

(provide start-server)

(require racket/tcp)


;; start-server: #:port number -> void
;;
;; An "ECHO" server.  Warning: does not return.
;;
;; To make things slightly more interesting, this will
;; uppercase all the string content received.
(define (start-server #:port port)
  (define max-waiting 1)
  (define reuse? #t)
  (define listen-ip "127.0.0.1")

  (define listener (tcp-listen port max-waiting reuse? listen-ip))
  (forever (define-values (in out)
             (tcp-accept listener))
           (ECHO in out)))


;; ECHO: input-port output-port -> void
;; Write out the uppercased content of the input-port
;; to the output port, until we reach eof.
(define (ECHO in out)
  (define line (read-line in))
  (cond [(eof-object? line)
         (close-output-port out)]
        [else
         (define LINE (string-upcase line))
         (write-string LINE out)
         (newline out)
         (flush-output out)
         (ECHO in out)]))


;; Syntax: repeat the body forever.
(define-syntax-rule (forever body ...)
  (let loop () body ... (loop)))


(module+ main
  (require racket/cmdline)
  ;; By default, use 9999 as the port.  This can be overridden
  ;; at the command line.
  (define current-port (make-parameter 9999))
  (void (command-line
         #:once-each [("-p" "--port") p "Port"
                      (current-port (string->number p))]))
  (start-server #:port (current-port)))

---------------------------------------------------------------


Note: I have not put any reasonable error trapping here, so this will
certainly die badly under a production environment.

Posted on the users mailing list.