Clozure CL中USOCKET无法正常工作的问题排查与解决
Clozure CL(CCL)中USOCKET无法正常使用的问题及解决办法
在Clozure CL(CCL)中无法使用USOCKET,相同代码在SBCL中可正常运行,且CCL自带的套接字功能也能正常工作。
以下代码片段在SBCL中可正常运行:
(let* ((sd (usocket:socket-connect "localhost" 1875)) (st (usocket:socket-stream sd))) (write-line (format nil "hello from ~A + usocket." (lisp-implementation-type)) st) (finish-output st))
但在CCL中运行时会触发USOCKET:CONNECTION-REFUSED-ERROR错误。
可排除防火墙问题,原因有二:
- Windows和Linux设备均出现该问题,但SBCL可正常运行;
- 使用CCL原生套接字时可正常连接:
(with-open-socket (socket :address-family :internet :type :stream :remote-host "localhost" :remote-port 1875 :reuse-address t) (format socket "~A." (format nil "Hello from ~A + native ccl sockets." (lisp-implementation-type))) (force-output socket)) ;; works!
困惑点:为何USOCKET函数无法在CCL中访问网络,但相同USOCKET代码在SBCL中可用,且CCL原生套接字库能正常连接同一地址/主机。尝试过不同端口、地址甚至UDP套接字,但USOCKET在两台设备的CCL中均无法工作,谷歌搜索未发现这是常见问题。
编辑1:排查已打开的UDP套接字,在Windows上使用netstat,Linux上使用ss -u -pa检查后,发现即使无法连接,CCL中仍有UDP套接字处于打开状态:
- 直接使用CCL套接字,或在SBCL中使用USOCKET时,UDP套接字采用常规UDP IPv4协议;
- 在CCL中使用USOCKET时,协议为UDPV6,且使用IPv6版本的回环地址[::1]而非127.0.0.1。
Windows和Linux设备均存在此情况,推测USOCKET在CCL中强制使用IPv6是问题根源。
尝试强制使用IPv4,将UDP套接字绑定到"127.0.0.1"而非"localhost",触发如下错误:
The condition Address family for hostname not supported (error #-9) during nameserver operation in getaddrinfo occurred with errno: 0. [Condition of type USOCKET:UNKNOWN-ERROR]
不确定是系统配置有误,还是问题出在USOCKET或CCL本身。
编辑2:问题已解决,原因是使用了旧版本USOCKET,只需执行(ql:update-all-dists)即可。
内容的提问来源于stack exchange,提问作者Oddi T
相关产品推荐
相关产品推荐

