Jorge Tavares <j
...@student.dei.uc.pt> writes:
> Hello all,
> I wanted to try to make a simple client server aplication with
> TCP sockets but I was unable to find information on the subject.
> The books I have don't talk about it and I have tried to find some
> web pages but didn't get anything. I've also tried to look in
> deja news but the serach results didn't give me a clear picture
> of the subject. I was able to realise that there must be something
> like open-tcp-stream and then work like a normal stream but I
> think there is more to the subject. If somebody would be kind
> enough to point me in some direction I would be apreciate.
> Thanks !
> Jorge
Access to sockets is not part of the ANSI CL standard, so the details
of this will vary between implementations, although the general
principle (that you describe above) will be similar. Erik has already
posted hints for ACL, here are some more for other systems:
a) Get cl-http, which would include implementation specific code for
listening and opening on sockets for nearly all implementations
(see http://www.ai.mit.edu/projects/iiip/doc/cl-http/home-page.html)
b) For CMUCL, this is the skeleton of code that is needed to listen on
a socket and spawn functions that handle connections (this uses
multi-processing, so will only work in this way on iA32):
(defun ip-address-string (address)
(format nil "~D.~D.~D.~D"
(ldb (byte 8 24) address)
(ldb (byte 8 16) address)
(ldb (byte 8 8) address)
(ldb (byte 8 0) address)))
(defun http-listener (port server)
(let ((fd (ext:create-inet-listener port)))
(unless fd (error "Cannot bind port ~D." port))
(unwind-protect
(progn
(setf (process-name *current-process*)
(format nil
"HTTP connection listener on port ~D with server ~A"
port server))
(format t "~&;;; Started lisp connection listener on ~
port ~d for server ~A~%" port server)
(loop
;; Wait for new connection
(process-wait-until-fd-usable fd :input)
#+CLASH-DEBUG
(format t "~&;;; At ~D Got Connection...~%"
(get-internal-real-time))
(multiple-value-bind (new-fd remote-host)
(ext:accept-tcp-connection fd)
#+CLASH-DEBUG
(format t "~&;;; At ~D Have Connection...~%"
(get-internal-real-time))
(let* ((host-entry (ext:lookup-host-entry remote-host))
(stream (sys:make-fd-stream new-fd :input t :output t))
(connection (make-instance 'simple-connection
:stream stream)))
#+CLASH-DEBUG
(format t "~&;;; At ~D Established Connection...~%"
(get-internal-real-time))
(make-process
#'(lambda ()
(serve-connection server connection))
:name (format nil "HTTP connection from ~A"
(if host-entry
(ext:host-entry-name host-entry)
(ip-address-string remote-host))))))))
(when fd (unix:unix-close fd)))))
(defun start-http-listener (port server)
(make-process #'(lambda () (http-listener port server))))
(defun initialize-clash (&optional (idle-process mp::*initial-process*))
(setf mp::*idle-process* idle-process))
Regs, Pierre.
--
Pierre Mai <p...@acm.org> PGP and GPG keys at your nearest Keyserver
"One smaller motivation which, in part, stems from altruism is Microsoft-
bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]