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

SBCL sockets example, please?

2,623 views
Skip to first unread message

Mike G.

unread,
Jun 26, 2007, 12:06:32 PM6/26/07
to
Hello everyone,

Could some kind soul please cook me up a quicky SBCL sockets example?

I just need something tangible to play with to learn how to set up a
TCP socket on both sides.

How about a TCP server which listens on a port and responds with
"Even" or "Odd" as appropriate when the client side sends an integer?

Thanks for your help.

-Mike

Peter Hildebrandt

unread,
Jun 26, 2007, 5:06:35 PM6/26/07
to
On Tue, 26 Jun 2007 09:06:32 -0700, Mike G. <michael...@gmail.com>
wrote:

> Hello everyone,
>
> Could some kind soul please cook me up a quicky SBCL sockets example?

I use something like this

;; as a tool

(defun nslookup (hostname)
"Performs a DNS look up for HOSTNAME and returns the address as a
four element array, suitable for socket-connect. If HOSTNAME is
not found, a host-not-found-error condition is thrown."
(if hostname
(host-ent-address (get-host-by-name hostname))
nil))

;; open a server port

(defun tcp-server (&key (interface (machine-instance)) (port 8000)
(backlog 5))
"Returns a socket server bound to PORT on INTERFACE. Defaults to
(machine-instance):8000.
The queue size BACKLOG defaults to 5 connections."
(handler-case
(let ((server (make-instance 'sb-bsd-sockets:inet-socket :type :stream
:protocol :tcp)))
(socket-bind server (nslookup interface) port)
(socket-listen server backlog)
server)
(address-in-use-error ()
(format t "address ~A : ~A is already in use"
interface port)
(force-output)
nil)))

;; return a connection

(defun tcp-accept (server &key (timeout 30))
"Waits up to TIMEOUT (defaults to 30) seconds for a client to connect to
SERVER.
A new socket is returned, which is bound to the client connection. If a
timeout
occured, nil is returned."
(when server
(unless-timeout timeout
(socket-accept server))))

;; connect to a server

(defun tcp-connect (server port &optional (timeout 5))
"Returns a socket connected to SERVER:PORT. If an error occurs, or the
attempt times out
after TIMOUT (default 5) secons, nil is returned."
(when (and server port)
(handler-case
(unless-timeout timeout
(let ((socket (make-instance 'sb-bsd-sockets:inet-socket :type
:stream :protocol :tcp)))
(socket-connect socket (nslookup server) port)
socket))
(host-not-found-error ()
(format t "host ~A not found." server)
(force-output)
nil))))

;; so once tcp-connect has connected to a server, tcp-connect returns a
socket on the client ands tcp-accept on the server

;; print and read plain text

(defun tcp-print-raw (socket line)
"Print LINE to SOCKET. CRLF is added. Returns the number of bytes
written."
(when (and socket line)
(socket-send socket (concatenate 'string line (list #\return
#\newline)) nil)))

(defun tcp-read-raw (socket &key (maxsize 65536) (timeout 5))
"Reads one line from SOCKET, removes CRLF, and returns it. The buffer
size
is 65536 bytes, unless MAXSIZE is specified. If no result is received
within TIMEOUT seconds (defaults to 5), nil is returned."
(when socket
(if-timeout (timeout (format t "socket-receive timed out after ~A
seconds.~%" timeout) (force-output) nil)
(values (socket-receive socket nil maxsize)))))

;; print and read printable objects

(defun tcp-print (socket object)
"Writes OBJECT to SOCKET so that it can be received using tcp-read."
(when (and socket object)
(tcp-print-raw socket
(let ((ostream (make-string-output-stream)))
(print object ostream)
(get-output-stream-string ostream)))))

(defun tcp-read (socket &key (timeout 10) (maxsize 1048576))
"Reads and returns a lisp object from the connection SOCKET."
(when socket
(let ((s (tcp-read-raw socket :maxsize maxsize :timeout timeout)))
(when s
(with-input-from-string (istream s) (read istream nil nil))))))


Hope that gives you an idea.

A real world app needs a lot more errorhandling etc. Besides, I usually
create new threads on the server handling the sockets returned by
tcp-accept.

HTH,
Peter

>
> I just need something tangible to play with to learn how to set up a
> TCP socket on both sides.
>
> How about a TCP server which listens on a port and responds with
> "Even" or "Odd" as appropriate when the client side sends an integer?
>
> Thanks for your help.
>
> -Mike
>

--

Using Opera's revolutionary e-mail client: http://www.opera.com/mail/

zos...@gmail.com

unread,
Jun 27, 2007, 9:13:34 AM6/27/07
to

You might find this useful:

http://jsnell.iki.fi/tmp/echo-server.lisp


Mike G.

unread,
Jun 27, 2007, 9:27:26 AM6/27/07
to
On Jun 26, 5:06 pm, "Peter Hildebrandt" <pet...@icsi.berkeley.edu>
wrote:
> On Tue, 26 Jun 2007 09:06:32 -0700, Mike G. <michael.graf...@gmail.com>

> wrote:
>
> > Hello everyone,
>
> > Could some kind soul please cook me up a quicky SBCL sockets example?
>
> I use something like this
<snipped>

Thanks! This is exactly the sort of thing I was looking for to get my
feet wet.

Now, if you'll excuse me, I have a date w/ SLIME.

-M

0 new messages