我在普通的lisp中尝试一个简单的echo服务器(我使用clisp)。我在http://rosettacode.org/wiki/Echo_server#Common_Lisp
中尝试了这个例子CLISP版本(没有usocket)工作正常。
当我尝试usocket版本(使用clisp)时,我收到以下错误:
* - 条件 CDR :: INPUT不是列表 发生。
提前感谢您的回复, 迪米瑞斯
答案 0 :(得分:1)
我不确定答案,但我认为这可以追溯到等待输入和等待输入内部 。功能等待输入具有以下定义(缩写):
(defun wait-for-input (socket-or-sockets &key timeout ready-only)
"Waits for one or more streams to become ready for reading from
the socket. When `timeout' (a non-negative real number) is
specified, wait `timeout' seconds, or wait indefinitely when
it isn't specified. A `timeout' value of 0 (zero) means polling. …"
(unless (wait-list-p socket-or-sockets)
(let ((wl (make-wait-list (if (listp socket-or-sockets)
socket-or-sockets (list socket-or-sockets)))))
(multiple-value-bind
(socks to)
(wait-for-input wl :timeout timeout :ready-only ready-only)
(return-from wait-for-input
(values (if ready-only socks socket-or-sockets) to)))))
(let* ((start (get-internal-real-time))
(sockets-ready 0))
(dolist (x (wait-list-waiters socket-or-sockets))
(when (setf (state x)
#+(and win32 (or sbcl ecl)) nil ; they cannot rely on LISTEN
#-(and win32 (or sbcl ecl))
(if (and (stream-usocket-p x)
(listen (socket-stream x)))
:read
nil))
(incf sockets-ready)))
;; the internal routine is responsibe for
;; making sure the wait doesn't block on socket-streams of
;; which theready- socket isn't ready, but there's space left in the
;; buffer
(wait-for-input-internal socket-or-sockets
:timeout (if (zerop sockets-ready) timeout 0))
(let ((to-result (when timeout
(let ((elapsed (/ (- (get-internal-real-time) start)
internal-time-units-per-second)))
(when (< elapsed timeout)
(- timeout elapsed))))))
(values (if ready-only
(remove-if #'null (wait-list-waiters socket-or-sockets) :key #'state)
socket-or-sockets)
to-result))))
请注意,最后一部分使用
调用 wait-for-input-internal(wait-for-input-internal socket-or-sockets
:timeout (if (zerop sockets-ready) timeout 0))
现在,名称 socket-or-sockets 意味着它的值可以是单个套接字或套接字列表。但是,让我们来看看CLISP的 wait-for-input-internal 的定义(它在backend/<implementation>.lisp
中定义):
(defmethod wait-for-input-internal (wait-list &key timeout)
(with-mapped-conditions ()
(multiple-value-bind
(secs musecs)
(split-timeout (or timeout 1))
(dolist (x (wait-list-%wait wait-list))
(setf (cdr x) :INPUT))
(let* ((request-list (wait-list-%wait wait-list))
(status-list (if timeout
(socket:socket-status request-list secs musecs)
(socket:socket-status request-list)))
(sockets (wait-list-waiters wait-list)))
(do* ((x (pop sockets) (pop sockets))
(y (cdr (pop status-list)) (cdr (pop status-list))))
((null x))
(when (member y '(T :INPUT))
(setf (state x) :READ)))
wait-list))))
:INPUT 有两种用途。似乎等待列表的每个元素都应该是一个缺点,其cdr包含某种状态。也许用单个套接字调用 wait-for-input (毕竟,参数名称是 socket-or-sockets ,当调用 wait-for-input-internal ,它会期待一个列表。这可能导致后者在期待(<something> . :INPUT)
时获得((<something . :INPUT))
。我&#39;但是我不确定。但无论如何,错误来自这里的某个地方。