Component sbcl

You are here: All Systems / trivial-sockets / sbcl

(in-package :trivial-sockets)

(defun resolve-hostname (name)
  (cond
   ((eql name :any)  #(0 0 0 0))
   ((typep name '(vector * 4)) name)
   (t (car (sb-bsd-sockets:host-ent-addresses
            (sb-bsd-sockets:get-host-by-name name)
)
)
)
)
)


(defun open-stream (peer-host peer-port
                              &key (local-host :any) (local-port 0)
                              (external-format :default)
                              (element-type 'character)
                              (protocol :tcp)
)

  (unless (eql external-format :default)
    (error 'unsupported :feature :external-format)
)

  (handler-bind ((sb-bsd-sockets:socket-error
                  (lambda (c) (error 'socket-error :nested-error c))
)

                 (sb-bsd-sockets:name-service-error
                  (lambda (c) (error 'socket-error :nested-error c))
)
)

    (let ((s (make-instance 'sb-bsd-sockets:inet-socket
                            :type :stream
                            :protocol protocol
)
)

          (me (resolve-hostname local-host))
)

      (unless (and (equal me #(0 0 0 0)) (eql local-port 0))
        (sb-bsd-sockets:socket-bind s me local-port)
)

      (sb-bsd-sockets:socket-connect
       s (resolve-hostname peer-host) peer-port
)

      (sb-bsd-sockets:socket-make-stream  s :input t :output t
                                          :element-type element-type
                                          :buffering :full
)
)
)
)


(defun open-server (&key (host :any) (port 0)
                         (reuse-address t)
                         (backlog 1)
                         (protocol :tcp)
)

  "Returns a SERVER object and the port that was bound, as multiple values"
  (let ((sock (make-instance 'sb-bsd-sockets:inet-socket
                             :type :stream
                             :protocol protocol
)
)
)

    (when reuse-address
      (setf (sb-bsd-sockets:sockopt-reuse-address sock) t)
)

    (sb-bsd-sockets:socket-bind  sock (resolve-hostname host) port)
    (sb-bsd-sockets:socket-listen sock backlog)
    (multiple-value-bind (h p) (sb-bsd-sockets:socket-name sock)
      (declare (ignore h))
      (values sock p)
)
)
)


(defun close-server (server)
  (sb-bsd-sockets:socket-close server)
)


(defun accept-connection (socket
                          &key
                          (external-format :default)
                          (element-type 'character)
)

  (unless (eql external-format :default)
    (error 'unsupported :feature :external-format)
)

  (let ((s (sb-bsd-sockets:socket-accept socket)))
    (sb-bsd-sockets:socket-make-stream s
                                       :input t :output t
                                       :element-type element-type
                                       :buffering :full
)
)
)


Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.