[isidorus-cvs] r699 - trunk/playground

lgiessmann at common-lisp.net lgiessmann at common-lisp.net
Mon Aug 1 13:57:30 UTC 2011


Author: lgiessmann
Date: Mon Aug  1 06:57:28 2011
New Revision: 699

Log:
trunk: playground: added an interface to accept tcp-client-connections, receive data from clients and send data to clients

Added:
   trunk/playground/tcp-connector.lisp

Added: trunk/playground/tcp-connector.lisp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/playground/tcp-connector.lisp	Mon Aug  1 06:57:28 2011	(r699)
@@ -0,0 +1,70 @@
+;;+-----------------------------------------------------------------------------
+;;+  Isidorus
+;;+  (c) 2008-2010 Marc Kuester, Christoph Ludwig, Lukas Georgieff
+;;+
+;;+  Isidorus is freely distributable under the LLGPL license.
+;;+  You can find a detailed description in trunk/docs/LLGPL-LICENSE.txt and
+;;+  trunk/docs/LGPL-LICENSE.txt.
+;;+-----------------------------------------------------------------------------
+
+;; source: http://mihai.bazon.net/blog/howto-multi-threaded-tcp-server-in-common-lisp
+
+
+(defun make-server (&key (hostname "localhost") (port 8000))
+  (declare (string hostname) (number port))
+  (usocket:socket-listen hostname port :reuse-address t))
+
+
+(defun wait-for-client (server-socket)
+  (declare (usocket:stream-server-usocket server-socket))
+  (usocket:wait-for-input server-socket)
+  (usocket:socket-accept server-socket))
+
+
+(defun read-from-client (client-socket)
+  (declare (usocket:stream-usocket client-socket))
+  (let* ((header (read-tcp-header (usocket:socket-stream client-socket)))
+	 (payload (read-tcp-payload (usocket:socket-stream client-socket) header)))
+    (list :headers header
+	  :payload payload)))
+
+
+(defun read-tcp-header (stream)
+  (declare (Stream stream))
+  (let ((line (string-right-trim (list #\cr) (read-line stream))))
+    (if (string= "" line)
+	(list "")
+	(progn
+	  (append (list line) (read-tcp-header stream))))))
+
+
+(defun read-tcp-payload (stream header-list)
+  (declare (Stream stream)
+	   (list header-list))
+  (let ((content-length
+	 (let ((val
+		(loop for line in header-list
+		   when (search "content-length:" (string-downcase line) :test #'string=)
+		   return (let ((value (subseq line (length "content-length:"))))
+			    (parse-integer value)))))
+	   (if val val 0)))
+	(payload ""))
+    (dotimes (idx content-length payload)
+      (setf payload (concatenate 'string payload (string (read-char stream)))))))
+
+
+(defun send-to-client (client-socket message-string &key (content-type "text/plain"))
+  (declare (usocket:stream-usocket client-socket)
+	   (String message-string content-type))
+  (format (usocket:socket-stream client-socket)
+	  "~a~c~c~a~a~c~c~a~a~c~c~a~c~c~c~c~a"
+	  "HTTP/1.1 200 OK" #\return #\newline
+	  "Content-Length: " (write-to-string (length message-string)) #\return #\newline
+	  "Content-Type: " content-type #\return #\newline
+	  "Connection: close" #\return #\newline
+	  #\return #\newline
+	  message-string)
+  (force-output (usocket:socket-stream client-socket))
+  (usocket:socket-close client-socket))
+
+




More information about the Isidorus-cvs mailing list