Richard James Panturis Giuly <··@spam.com> writes:
> How do I access tcp sockets with lisp?
>
> thanks in advance
You don't say what Lisp implementation you're using or on what
platform, but if you're using CMUCL on something Unix-like this might
be worth a look:
http://ww.telent.net/lisp/sockets.html
Cheers,
g
From: Thom Goodsell
Subject: Re: Newbie Q. How do I use sockets?
Date:
Message-ID: <39589F45.1F45E0D4@cra.com>
Alas, the socket interface is not standardized, so we'll need to know
what Lisp you're using and, most likely, what platform.
Thom
Richard James Panturis Giuly wrote:
>
> How do I access tcp sockets with lisp?
>
> thanks in advance
>
> --
> ricky
> ······@surfsouth.com
From: Richard James Panturis Giuly
Subject: Re: Newbie Q. How do I use sockets?
Date:
Message-ID: <3958DF22.9632BE3C@spam.com>
Thom Goodsell wrote:
> Alas, the socket interface is not standardized, so we'll need to know
> what Lisp you're using and, most likely, what platform.
>
> Thom
I'm using ACL on a (Red Hat 6) Linux machine.
······@surfsouth.com
Richard James Panturis Giuly <··@spam.com> writes:
> Thom Goodsell wrote:
>
> > Alas, the socket interface is not standardized, so we'll need to know
> > what Lisp you're using and, most likely, what platform.
>
> I'm using ACL on a (Red Hat 6) Linux machine.
Here's a short example.
-matt
;;; Silly little example of using sockets in ACL. See whois(1)
;;; on your local Unix box for additional information.
;;; by R. Matthew Emerson <···@acm.org>, October 1999
(eval-when (:compile-toplevel :load-toplevel)
(require :socket)
(use-package :socket))
(in-package :cl-user)
(defconstant *whois-port* 43)
(defun whois (what &optional (server "whois.internic.net"))
(let ((port (ignore-errors (lookup-port "whois" "tcp"))))
(if (null port)
(setf port *whois-port*))
(with-open-stream (s (make-socket :remote-host server :remote-port port))
(format s "~a~c~c" what #\return #\linefeed)
(force-output s)
(do ((line (read-line s nil :eof) (read-line s nil :eof)))
((eq line :eof))
(princ line)
(terpri)))))
;;; some examples
#|
(whois "me67") ;look up yours truly
(whois "franz.com")
(whois "207.54.159.0" "whois.arin.net") ;use an alternate whois server
|#
--
Matt Emerson <···@grc.nasa.gov>
Stay on target. Stay on target!
Richard James Panturis Giuly <··@spam.com> writes:
> Thom Goodsell wrote:
>
> > Alas, the socket interface is not standardized, so we'll need to know
> > what Lisp you're using and, most likely, what platform.
> >
> > Thom
>
> I'm using ACL on a (Red Hat 6) Linux machine.
I'd just check out the simple examples in their
$ALLEGRO_HOME/doc/cl/sockets.htm directory or whatever it is.
dave
* Richard James Panturis Giuly <··@spam.com>
| How do I access tcp sockets with lisp?
There's a lot of stuff you can do, and then you can avoid most of
the problems with a few simple macros:
(defmacro with-network-server ((variable &key keep-open (host 0) port log-error options)
&body body)
"Set up a simple network server.
The server socket is opened on HOST:PORT, default *:PORT if no HOST is specified. Further socket
options may be supplied as a list of keyword-value pairs in OPTIONS.
The BODY is executed with VARIABLE (a symbol) bound to each incoming connection, which is gauranteed
to be closed upon exit from BODY unless KEEP-OPEN is true.
If a socket error occurs during socket creation, it is logged as a critical error (unless LOG-ERROR
is false) and the error is re-signaled. If not caught elsewhere, this form returns the error object.
An error when accepting a connection is ignored.
Errors in the body invoke the debugger for now, as do non-socket errors elsewhere."
(let ((server (gensym)))
`(let ((,server (handler-case (make-socket :connect :passive
:local-host ,host
:local-port ,port
,@options)
(socket-error (error)
(case (socket-error-code error)
((:address-in-use :address-not-available)
(signal error)
error)
(t
,(when log-error
`(write-system-log :critical
"Could not create server on ~A:~D:~%~A" ,host ,port error))
(signal error)
error))))))
(if (typep ,server 'socket)
(unwind-protect
(loop
(let ((,variable (accept-connection ,server)))
,(if keep-open
`(when (typep ,variable 'socket)
,@body)
`(when (typep ,variable 'socket)
(unwind-protect
(progn ,@body)
(when (typep ,variable 'socket)
(close ,variable)))))))
(when (typep ,server 'socket)
(close ,server)))
,server))))
(defmacro with-network-client ((variable &key keep-open (host 0) port log-error options)
&body body)
"Set up a simple network client.
The client socket is opened to HOST:PORT, default <localhost>:PORT if no host is specified
and bound to VARIABLE across BODY, to be closed on exist, unless kEEP-OPEN is true.
If a socket error occurs during socket creation, it is logged as a notice (unless LOG-ERROR is
false) and the error is re-signaled. If not caught elsewhere, this form returns the error object."
`(let ((,variable (handler-case (make-socket :connect :active
:remote-host ,host
:remote-port ,port
,@options)
(socket-error (error)
(case (socket-error-code error)
((:network-down :network-unreachable :network-reset
:host-down :host-unreachable)
(signal error)
error)
((:connection-timed-out :connection-refused)
nil)
(t
,(when log-error
`(write-system-log :notice
"Could not open connection to ~A:~D:~%~A" ,host ,port error))
(signal error)
error))))))
,(if keep-open
`(if (typep ,variable 'socket)
(progn ,@body)
,variable)
`(if (typep ,variable 'socket)
(unwind-protect
(progn ,@body)
(when (typep ,variable 'socket)
(close, variable)))
,variable))))
Let's ignore the write-system-log call for now.
I have a slightly modified version to obey the TELNET protocol, but
it's too much to post here. The whois client goes like this:
Example:
(with-telnet-client (whois :host "whois.internic.net" :port "whois")
(write-line "clemacs.org" whois) ;Automatic CRLF and force-output
(ignore-errors (loop (write-line (read-line whois))))
(values))
#:Erik
--
If this is not what you expected, please alter your expectations.