Skip to content

Instantly share code, notes, and snippets.

@DexterHaslem
Created November 20, 2013 01:48
Show Gist options
  • Save DexterHaslem/7556195 to your computer and use it in GitHub Desktop.
Save DexterHaslem/7556195 to your computer and use it in GitHub Desktop.
(require :sb-bsd-sockets)
(defpackage echo-server
(:use :cl :sb-bsd-sockets))
(in-package echo-server)
(defvar *port* 7000)
(defun make-echoer (stream id disconnector)
(lambda (_)
(declare (ignore _))
(handler-case
(let ((line (read-line stream)))
(setf line (subseq line 0 (1- (length line))))
(cond ((string= line "quit")
(funcall disconnector))
(t
(format t "~a: ~a~%" id line)
(format stream "~a: ~a~%" id line)
(force-output stream))))
(end-of-file ()
(funcall disconnector)))))
(defun make-disconnector (socket id)
(lambda ()
(let ((fd (socket-file-descriptor socket)))
(format t "~a: closing~%" id)
(sb-impl::invalidate-descriptor fd)
(socket-close socket))))
(defun serve (socket id)
(let ((stream (socket-make-stream socket :output t :input t))
(fd (socket-file-descriptor socket)))
(sb-impl::add-fd-handler fd
:input
(make-echoer stream
id
(make-disconnector socket id)))))
(defun echo-server (&optional (port *port*))
(let ((socket (make-instance 'inet-socket :type :stream :protocol :tcp))
(counter 0))
(socket-bind socket #(127 0 0 1) port)
(socket-listen socket 5)
(sb-impl::add-fd-handler (socket-file-descriptor socket)
:input
(lambda (_)
(declare (ignore _))
(incf counter)
(format t "Accepted client ~A~%" counter)
(serve (socket-accept socket) counter)))))
#+sb-thread
(sb-thread:make-thread (lambda ()
(echo-server)
(loop
(sb-impl::serve-all-events))))
#-sb-thread
(echo-server)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment