Update ISYS::%PTSNAME to latest libfixposix
[iolib.git] / examples / ex2-server.lisp
blob0057b2d298771e36f226bdb56b6a3980a0e6faad
1 (in-package :iolib.examples)
3 ;;;; This file was originally written by Peter Keller (psilord@cs.wisc.edu)
4 ;;;; and this code is released under the same license as IOLib.
6 ;;;; This next example is a more common-lisp-like style, and when
7 ;;;; appropriate it will be used for the rest of the examples.
9 ;;;; It implements an IPV4 blocking i/o iterative server which serves
10 ;;;; clients sequentially forever. There is no error handling of
11 ;;;; client boundary conditions such as a client connection but then
12 ;;;; immediately closing the connection. Handling errors will be in
13 ;;;; later examples.
15 (defun run-ex2-server (&key (port *port*))
17 ;; This is an appropriate use of with-open-socket since we are
18 ;; synchronously and iteratively handling client connections.
19 (with-open-socket
20 (server :connect :passive
21 :address-family :internet
22 :type :stream
23 :ipv6 nil
24 :external-format '(:utf-8 :eol-style :crlf))
25 (format t "Created socket: ~A[fd=~A]~%" server (socket-os-fd server))
27 ;; Bind the socket to all interfaces with specified port.
28 (bind-address server +ipv4-unspecified+ :port port :reuse-addr t)
29 (format t "Bound socket: ~A~%" server)
31 ;; Start listening on the server socket
32 (listen-on server :backlog 5)
33 (format t "Listening on socket bound to: ~A:~A~%"
34 (local-host server)
35 (local-port server))
37 ;; ex-0b
38 ;; Keep accepting connections forever.
39 (loop
40 (format t "Waiting to accept a connection...~%")
42 ;; Using with-accept-connection, when this form returns it will
43 ;; automatically close the client connection.
44 (with-accept-connection (client server :wait t)
45 ;; When we get a new connection, show who it is from.
46 (multiple-value-bind (who rport)
47 (remote-name client)
48 (format t "Got a connnection from ~A:~A!~%" who rport))
50 ;; Since we're using a internet TCP stream, we can use format
51 ;; with it. However, we should be sure to finish-output in
52 ;; order that all the data is sent.
53 (multiple-value-bind (s m h d mon y)
54 (get-decoded-time)
55 (format t "Sending the time...")
56 (format client "~A/~A/~A ~A:~A:~A~%" mon d y h m s)
57 (finish-output client)
58 (format t "Sent!~%")
59 (finish-output)
60 t)))))
61 ;; ex-0e