[racket] sustained network
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.