Sketch of simple 1-in,1-out UDP chassis, with error handling
This commit is contained in:
parent
ac1d493528
commit
b72b78119f
|
@ -0,0 +1,56 @@
|
|||
#lang racket/base
|
||||
|
||||
;; Simple imperative UDP server harness.
|
||||
|
||||
(require racket/udp)
|
||||
(require "dump-bytes.rkt")
|
||||
|
||||
(provide (struct-out udp-packet)
|
||||
start-udp-service)
|
||||
|
||||
;; A UdpPacket is a (udp-packet Bytes String Uint16), and represents
|
||||
;; either a received UDP packet and the source of the packet, or a UDP
|
||||
;; packet ready to be sent along with the address to which it should
|
||||
;; be sent.
|
||||
(struct udp-packet (body host port) #:transparent)
|
||||
|
||||
;; Starts a generic request/reply UDP server on the given port.
|
||||
(define (start-udp-service
|
||||
port-number ;; Uint16
|
||||
packet-handler ;; UdpPacket ServerState -> ListOf<UdpPacket> ServerState
|
||||
initial-state ;; ServerState
|
||||
#:service-name
|
||||
[service-name (format "anonymous UDP service on port ~v" port-number)]
|
||||
#:packet-size-limit
|
||||
[packet-size-limit 65536])
|
||||
(define s (udp-open-socket #f #f)) ;; the server socket
|
||||
(udp-bind! s #f port-number) ;; bind it to the port we were given
|
||||
|
||||
(define (service-loop state)
|
||||
(service-loop
|
||||
(with-handlers ((exn:break? (lambda (e) (raise e)))
|
||||
(exn? (lambda (e)
|
||||
(printf "Error in ~a:~n~v~n~n" service-name e)
|
||||
(flush-output)
|
||||
state)))
|
||||
(read-and-process-request state))))
|
||||
|
||||
(define (read-and-process-request old-state)
|
||||
(define buffer (make-bytes packet-size-limit))
|
||||
(define-values (packet-length source-hostname source-port)
|
||||
(udp-receive! s buffer))
|
||||
(define packet (subbytes buffer 0 packet-length))
|
||||
|
||||
(printf "----------------------------------------~n~v~n" packet)
|
||||
(dump-bytes! buffer packet-length)
|
||||
(flush-output)
|
||||
|
||||
(define-values (reply-packets new-state)
|
||||
(packet-handler (udp-packet packet source-hostname source-port) old-state))
|
||||
|
||||
(for-each (lambda (p)
|
||||
(udp-send-to s (udp-packet-host p) (udp-packet-port p) (udp-packet-body p)))
|
||||
reply-packets)
|
||||
new-state)
|
||||
|
||||
(service-loop initial-state))
|
Loading…
Reference in New Issue