Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Newbie Q. How do I use sockets?

4 views
Skip to first unread message

Richard James Panturis Giuly

unread,
Jun 26, 2000, 3:00:00 AM6/26/00
to
How do I access tcp sockets with lisp?

thanks in advance

--
ricky
rgi...@surfsouth.com

Graham Ward

unread,
Jun 27, 2000, 3:00:00 AM6/27/00
to
Richard James Panturis Giuly <n...@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

Thom Goodsell

unread,
Jun 27, 2000, 3:00:00 AM6/27/00
to
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
> rgi...@surfsouth.com

Richard James Panturis Giuly

unread,
Jun 27, 2000, 3:00:00 AM6/27/00
to

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.

rgi...@surfsouth.com


R Matthew Emerson

unread,
Jun 27, 2000, 3:00:00 AM6/27/00
to
Richard James Panturis Giuly <n...@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 <r...@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 <r...@grc.nasa.gov>
Stay on target. Stay on target!

David Bakhash

unread,
Jun 28, 2000, 3:00:00 AM6/28/00
to
Richard James Panturis Giuly <n...@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

Erik Naggum

unread,
Jun 28, 2000, 3:00:00 AM6/28/00
to
* Richard James Panturis Giuly <n...@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.

0 new messages