From ctian at common-lisp.net Sat Sep 11 13:34:28 2010 From: ctian at common-lisp.net (Chun Tian (binghe)) Date: Sat, 11 Sep 2010 09:34:28 -0400 Subject: [usocket-cvs] r554 - in usocket/trunk: backend test Message-ID: Author: ctian Date: Sat Sep 11 09:34:27 2010 New Revision: 554 Log: New ABCL backend using latest JAVA interface. Added: usocket/trunk/backend/abcl.lisp (contents, props changed) usocket/trunk/test/test-condition.lisp (contents, props changed) Added: usocket/trunk/backend/abcl.lisp ============================================================================== --- (empty file) +++ usocket/trunk/backend/abcl.lisp Sat Sep 11 09:34:27 2010 @@ -0,0 +1,202 @@ +;;;; $Id$ +;;;; $URL$ + +;;;; New ABCL networking support (replacement to old armedbear.lisp) +;;;; Author: Chun Tian (binghe) + +;;;; See LICENSE for licensing information. + +(in-package :usocket) + +;;; Java Classes ($*...) +(defvar $*boolean (jclass "boolean")) +(defvar $*int (jclass "int")) +(defvar $*DatagramSocket (jclass "java.net.DatagramSocket")) +(defvar $*Inet4Address (jclass "java.net.Inet4Address")) +(defvar $*InetAddress (jclass "java.net.InetAddress")) +(defvar $*InetSocketAddress (jclass "java.net.InetSocketAddress")) +(defvar $*ServerSocket (jclass "java.net.ServerSocket")) +(defvar $*Socket (jclass "java.net.Socket")) +(defvar $*SocketAddress (jclass "java.net.SocketAddress")) +(defvar $*String (jclass "java.lang.String")) + +;;; Java Constructor ($%.../n) +(defvar $%DatagramSocket/0 (jconstructor $*DatagramSocket)) +(defvar $%InetSocketAddress/1 (jconstructor $*InetSocketAddress $*int)) +(defvar $%InetSocketAddress/2 (jconstructor $*InetSocketAddress $*InetAddress $*int)) +(defvar $%ServerSocket/0 (jconstructor $*ServerSocket)) +(defvar $%ServerSocket/1 (jconstructor $*ServerSocket $*int)) +(defvar $%ServerSocket/2 (jconstructor $*ServerSocket $*int $*int)) +(defvar $%ServerSocket/3 (jconstructor $*ServerSocket $*int $*int $*InetAddress)) +(defvar $%Socket/0 (jconstructor $*Socket)) +(defvar $%Socket/2 (jconstructor $*Socket $*InetAddress $*int)) +(defvar $%Socket/4 (jconstructor $*Socket $*InetAddress $*int $*InetAddress $*int)) + +;;; Java Methods ($@...[/Class]/n) +(defvar $@accept/0 (jmethod $*ServerSocket "accept")) +(defvar $@bind/1 (jmethod $*ServerSocket "bind" $*SocketAddress)) +(defvar $@bind/2 (jmethod $*ServerSocket "bind" $*SocketAddress $*int)) +(defvar $@close/ServerSocket/0 (jmethod $*ServerSocket "close")) +(defvar $@close/Socket/0 (jmethod $*Socket "close")) +(defvar $@connect/1 (jmethod $*Socket "connect" $*SocketAddress)) +(defvar $@connect/2 (jmethod $*Socket "connect" $*SocketAddress $*int)) +(defvar $@getAddress/0 (jmethod $*Inet4Address "getAddress")) +(defvar $@getAllByName/1 (jmethod $*InetAddress "getAllByName" $*String)) +(defvar $@getByName/1 (jmethod $*InetAddress "getByName" $*String)) +(defvar $@getHostName/0 (jmethod $*InetAddress "getHostName")) +(defvar $@getInetAddress/ServerSocket/0 (jmethod $*ServerSocket "getInetAddress")) +(defvar $@getInetAddress/Socket/0 (jmethod $*Socket "getInetAddress")) +(defvar $@getLocalAddress/Socket/0 (jmethod $*Socket "getLocalAddress")) +(defvar $@getLocalPort/ServerSocket/0 (jmethod $*ServerSocket "getLocalPort")) +(defvar $@getLocalPort/Socket/0 (jmethod $*Socket "getLocalPort")) +(defvar $@getPort/Socket/0 (jmethod $*Socket "getPort")) +(defvar $@setReuseAddress/1 (jmethod $*ServerSocket "setReuseAddress" $*boolean)) + +;;; Wrapper functions (return-type: java-object) +(defun %get-address (address) + (jcall $@getAddress/0 address)) +(defun %get-all-by-name (string) ; return a simple vector + (jstatic $@getAllByName/1 $*InetAddress string)) +(defun %get-by-name (string) + (jstatic $@getByName/1 $*InetAddress string)) + +;;; HANDLE-CONTITION + +(defun handle-condition (condition &optional (socket nil)) + (typecase condition + (java-exception + (let ((java-cause (java-exception-cause condition))) + (let* ((usock-error (cdr (assoc (jclass-of java-cause) +abcl-error-map+ + :test #'string=))) + (usock-error (if (functionp usock-error) + (funcall usock-error condition) + usock-error)) + (nameserver-error (cdr (assoc (jclass-of java-cause) +abcl-nameserver-error-map+ + :test #'string=)))) + (if nameserver-error + (error nameserver-error :host-or-ip nil) + (when usock-error + (error usock-error :socket socket)))))))) + +(defparameter +abcl-error-map+ + `(;("java.io.IOException" . ) + ("java.net.ConnectException" . connection-refused-error) + ("java.net.SocketTimeoutException" . timeout-error) + ("java.net.BindException" . operation-not-permitted-error))) + +(defparameter +abcl-nameserver-error-map+ + `(("java.net.UnknownHostException" . ns-host-not-found-error))) + +;;; GET-HOSTS-BY-NAME + +(defun get-address (address) + (let* ((array (%get-address address)) + (length (jarray-length array))) + (labels ((jbyte (n) + (let ((byte (jarray-ref array n))) + (if (plusp byte) + byte + (+ 256 byte))))) + (if (= 4 length) + (vector (jbyte 0) (jbyte 1) (jbyte 2) (jbyte 3)) + nil)))) ; not a IPv4 address?! + +(defun get-hosts-by-name (name) + (with-mapped-conditions () + (map 'list #'get-address (%get-all-by-name name)))) + +(defun host-to-inet4 (host) + "USOCKET host formats to Java Inet4Address, used internally." + (%get-by-name (host-to-hostname host))) + +;;; GET-HOST-BY-ADDRESS +(defun get-host-by-address (host) + (let ((inet4 (host-to-inet4 host))) + (with-mapped-conditions () + (jcall $@getHostName/0 inet4)))) + +;;; SOCKET-CONNECT + +(defun socket-connect (host port &key (protocol :stream) (element-type 'character) + timeout deadline (nodelay t nodelay-supplied-p) + local-host local-port) + (declare (type integer timeout)) + (if (eq protocol :stream) + (let* ((socket (with-mapped-conditions () + (if (or local-host local-port) + (jnew $%Socket/4 (host-to-inet4 host) port (host-to-inet4 local-host) local-port) + (if timeout + (let ((socket (jnew $%Socket/0)) + (address (jnew $%InetSocketAddress/2 (host-to-inet4 host) port))) + (jcall $@connect/2 socket address timeout) + socket) + (jnew $%Socket/2 (host-to-inet4 host) port))))) + (stream (ext:get-socket-stream socket :element-type element-type)) + (usocket (make-stream-socket :stream stream :socket socket))) + usocket) + (socket-connect-for-udp host port :timeout timeout :local-host local-host :local-port local-port))) + +(defun socket-connect-for-udp (host port &key timeout local-host local-port) + ) + +(defun socket-listen (host port &key reuseaddress (element-type 'character) + (reuse-address nil reuse-address-supplied-p) + (backlog 5 backlog-supplied-p)) + (let ((socket (jnew $%ServerSocket/0)) + (endpoint (jnew $%InetSocketAddress/2 (host-to-inet4 host) port))) + #+ignore ;; TODO: java.lang.IllegalArgumentException? + (when reuse-address-supplied-p + (jcall $@setReuseAddress/1 socket reuse-address)) + (with-mapped-conditions (socket) + (if backlog-supplied-p + (jcall $@bind/2 socket endpoint backlog) + (jcall $@bind/1 socket endpoint))) + (make-stream-server-socket socket :element-type element-type))) + +(defmethod socket-accept ((socket stream-server-usocket) &key (element-type 'character)) + (with-mapped-conditions (socket) + (let* ((client-socket (jcall $@accept/0 socket)) + (stream (ext:get-socket-stream client-socket :element-type element-type))) + (make-stream-socket :stream stream :socket client-socket)))) + +(defmethod socket-close :before ((usocket usocket)) + (when (wait-list usocket) + (remove-waiter (wait-list usocket) usocket))) + +(defmethod socket-close ((usocket usocket)) + (with-mapped-conditions (usocket) + (jcall $@close/Socket/0 (socket usocket)))) + +(defmethod socket-close ((usocket stream-server-usocket)) + (with-mapped-conditions (usocket) + (jcall $@close/ServerSocket/0 (socket usocket)))) + +(defmethod socket-close ((usocket stream-usocket)) + (with-mapped-conditions (usocket) + (close (socket-stream usocket)))) + +(defmethod get-local-name ((usocket usocket)) + (values (get-local-address usocket) + (get-local-port usocket))) + +(defmethod get-peer-name ((usocket stream-usocket)) + (values (get-peer-address usocket) + (get-peer-port usocket))) + +(defmethod get-local-address ((usocket usocket)) + (get-address (jcall $@getLocalAddress/Socket/0 (socket usocket)))) + +(defmethod get-local-address ((usocket stream-server-usocket)) + (get-address (jcall $@getInetAddress/ServerSocket/0 (socket usocket)))) + +(defmethod get-peer-address ((usocket usocket)) + (get-address (jcall $@getInetAddress/Socket/0 (socket usocket)))) + +(defmethod get-local-port ((usocket usocket)) + (jcall $@getLocalPort/Socket/0 (socket usocket))) + +(defmethod get-local-port ((usocket stream-server-usocket)) + (jcall $@getLocalPort/ServerSocket/0 (socket usocket))) + +(defmethod get-peer-port ((usocket usocket)) + (jcall $@getPort/Socket/0 (socket usocket))) Added: usocket/trunk/test/test-condition.lisp ============================================================================== --- (empty file) +++ usocket/trunk/test/test-condition.lisp Sat Sep 11 09:34:27 2010 @@ -0,0 +1,28 @@ +;;;; $Id$ +;;;; $URL$ + +(in-package :usocket-test) + +(deftest ns-host-not-found-error.1 + (with-caught-conditions (usocket:ns-host-not-found-error nil) + (usocket:socket-connect "xxx" 123) + t) + nil) + +(deftest timeout-error.1 + (with-caught-conditions (usocket:timeout-error nil) + (usocket:socket-connect "common-lisp.net" 81 :timeout 1) + t) + nil) + +(deftest connection-refused-error.1 + (with-caught-conditions (usocket:connection-refused-error nil) + (usocket:socket-connect "common-lisp.net" 81) + t) + nil) + +(deftest operation-not-permitted-error.1 + (with-caught-conditions (usocket:operation-not-permitted-error nil) + (usocket:socket-listen "0.0.0.0" 81) + t) + nil) From ctian at common-lisp.net Mon Sep 13 15:33:20 2010 From: ctian at common-lisp.net (Chun Tian (binghe)) Date: Mon, 13 Sep 2010 11:33:20 -0400 Subject: [usocket-cvs] r555 - in usocket/trunk: . backend vendor Message-ID: Author: ctian Date: Mon Sep 13 11:33:20 2010 New Revision: 555 Log: ABCL: replace old JDI-based implementation with new implementation. Removed: usocket/trunk/backend/armedbear.lisp usocket/trunk/vendor/abcl-jdi.lisp Modified: usocket/trunk/backend/abcl.lisp usocket/trunk/package.lisp usocket/trunk/usocket.asd usocket/trunk/usocket.lisp Modified: usocket/trunk/backend/abcl.lisp ============================================================================== --- usocket/trunk/backend/abcl.lisp (original) +++ usocket/trunk/backend/abcl.lisp Mon Sep 13 11:33:20 2010 @@ -8,20 +8,49 @@ (in-package :usocket) +;;; Symbols in JAVA package +(eval-when (:compile-toplevel :load-toplevel :execute) + (defparameter *java-package-symbols* + '(java:jarray-length + java:jarray-ref + java:java-exception + java:java-exception-cause + java:jconstructor + java:jcall + java:jclass + java:jclass-of + java:jfield + java:jmethod + java:jnew + java:jstatic + java:make-immediate-object)) + (import *java-package-symbols*)) + ;;; Java Classes ($*...) (defvar $*boolean (jclass "boolean")) (defvar $*int (jclass "int")) +(defvar $*long (jclass "long")) +(defvar $*DatagramChannel (jclass "java.nio.channels.DatagramChannel")) (defvar $*DatagramSocket (jclass "java.net.DatagramSocket")) (defvar $*Inet4Address (jclass "java.net.Inet4Address")) (defvar $*InetAddress (jclass "java.net.InetAddress")) (defvar $*InetSocketAddress (jclass "java.net.InetSocketAddress")) +(defvar $*Iterator (jclass "java.util.Iterator")) +(defvar $*SelectableChannel (jclass "java.nio.channels.SelectableChannel")) +(defvar $*SelectionKey (jclass "java.nio.channels.SelectionKey")) +(defvar $*Selector (jclass "java.nio.channels.Selector")) (defvar $*ServerSocket (jclass "java.net.ServerSocket")) +(defvar $*ServerSocketChannel (jclass "java.nio.channels.ServerSocketChannel")) +(defvar $*Set (jclass "java.util.Set")) (defvar $*Socket (jclass "java.net.Socket")) (defvar $*SocketAddress (jclass "java.net.SocketAddress")) +(defvar $*SocketChannel (jclass "java.nio.channels.SocketChannel")) (defvar $*String (jclass "java.lang.String")) ;;; Java Constructor ($%.../n) (defvar $%DatagramSocket/0 (jconstructor $*DatagramSocket)) +(defvar $%DatagramSocket/1 (jconstructor $*DatagramSocket $*int)) +(defvar $%DatagramSocket/2 (jconstructor $*DatagramSocket $*int $*InetAddress)) (defvar $%InetSocketAddress/1 (jconstructor $*InetSocketAddress $*int)) (defvar $%InetSocketAddress/2 (jconstructor $*InetSocketAddress $*InetAddress $*int)) (defvar $%ServerSocket/0 (jconstructor $*ServerSocket)) @@ -34,23 +63,65 @@ ;;; Java Methods ($@...[/Class]/n) (defvar $@accept/0 (jmethod $*ServerSocket "accept")) -(defvar $@bind/1 (jmethod $*ServerSocket "bind" $*SocketAddress)) -(defvar $@bind/2 (jmethod $*ServerSocket "bind" $*SocketAddress $*int)) +(defvar $@bind/DatagramSocket/1 (jmethod $*DatagramSocket "bind" $*SocketAddress)) +(defvar $@bind/ServerSocket/1 (jmethod $*ServerSocket "bind" $*SocketAddress)) +(defvar $@bind/ServerSocket/2 (jmethod $*ServerSocket "bind" $*SocketAddress $*int)) +(defvar $@bind/Socket/1 (jmethod $*Socket "bind" $*SocketAddress)) +(defvar $@channel/0 (jmethod $*SelectionKey "channel")) +(defvar $@close/DatagramSocket/0 (jmethod $*DatagramSocket "close")) +(defvar $@close/Selector/0 (jmethod $*Selector "close")) (defvar $@close/ServerSocket/0 (jmethod $*ServerSocket "close")) (defvar $@close/Socket/0 (jmethod $*Socket "close")) -(defvar $@connect/1 (jmethod $*Socket "connect" $*SocketAddress)) -(defvar $@connect/2 (jmethod $*Socket "connect" $*SocketAddress $*int)) +(defvar $@configureBlocking/1 (jmethod $*SelectableChannel "configureBlocking" $*boolean)) +(defvar $@connect/DatagramChannel/1 (jmethod $*DatagramChannel "connect" $*SocketAddress)) +(defvar $@connect/Socket/1 (jmethod $*Socket "connect" $*SocketAddress)) +(defvar $@connect/Socket/2 (jmethod $*Socket "connect" $*SocketAddress $*int)) +(defvar $@connect/SocketChannel/1 (jmethod $*SocketChannel "connect" $*SocketAddress)) (defvar $@getAddress/0 (jmethod $*Inet4Address "getAddress")) (defvar $@getAllByName/1 (jmethod $*InetAddress "getAllByName" $*String)) (defvar $@getByName/1 (jmethod $*InetAddress "getByName" $*String)) +(defvar $@getChannel/DatagramSocket/0 (jmethod $*DatagramSocket "getChannel")) +(defvar $@getChannel/ServerSocket/0 (jmethod $*ServerSocket "getChannel")) +(defvar $@getChannel/Socket/0 (jmethod $*Socket "getChannel")) (defvar $@getHostName/0 (jmethod $*InetAddress "getHostName")) +(defvar $@getInetAddress/DatagramSocket/0 (jmethod $*DatagramSocket "getInetAddress")) (defvar $@getInetAddress/ServerSocket/0 (jmethod $*ServerSocket "getInetAddress")) (defvar $@getInetAddress/Socket/0 (jmethod $*Socket "getInetAddress")) +(defvar $@getLocalAddress/DatagramSocket/0 (jmethod $*DatagramSocket "getLocalAddress")) (defvar $@getLocalAddress/Socket/0 (jmethod $*Socket "getLocalAddress")) +(defvar $@getLocalPort/DatagramSocket/0 (jmethod $*DatagramSocket "getLocalPort")) (defvar $@getLocalPort/ServerSocket/0 (jmethod $*ServerSocket "getLocalPort")) (defvar $@getLocalPort/Socket/0 (jmethod $*Socket "getLocalPort")) +(defvar $@getPort/DatagramSocket/0 (jmethod $*DatagramSocket "getPort")) (defvar $@getPort/Socket/0 (jmethod $*Socket "getPort")) +(defvar $@hasNext/0 (jmethod $*Iterator "hasNext")) +(defvar $@iterator/0 (jmethod $*Set "iterator")) +(defvar $@next/0 (jmethod $*Iterator "next")) +(defvar $@open/DatagramChannel/0 (jmethod $*DatagramChannel "open")) +(defvar $@open/Selector/0 (jmethod $*Selector "open")) +(defvar $@open/ServerSocketChannel/0 (jmethod $*ServerSocketChannel "open")) +(defvar $@open/SocketChannel/0 (jmethod $*SocketChannel "open")) +(defvar $@register/2 (jmethod $*SelectableChannel "register" $*Selector $*int)) +(defvar $@select/0 (jmethod $*Selector "select")) +(defvar $@select/1 (jmethod $*Selector "select" $*long)) +(defvar $@selectedKeys/0 (jmethod $*Selector "selectedKeys")) (defvar $@setReuseAddress/1 (jmethod $*ServerSocket "setReuseAddress" $*boolean)) +(defvar $@setSoTimeout/DatagramSocket/1 (jmethod $*DatagramSocket "setSoTimeout" $*int)) +(defvar $@setSoTimeout/Socket/1 (jmethod $*Socket "setSoTimeout" $*int)) +(defvar $@setTcpNoDelay/1 (jmethod $*Socket "setTcpNoDelay" $*boolean)) +(defvar $@socket/DatagramChannel/0 (jmethod $*DatagramChannel "socket")) +(defvar $@socket/ServerSocketChannel/0 (jmethod $*ServerSocketChannel "socket")) +(defvar $@socket/SocketChannel/0 (jmethod $*SocketChannel "socket")) +(defvar $@validOps/0 (jmethod $*SelectableChannel "validOps")) + +;;; Java Field Variables ($+...) +(defvar $+op-accept (jfield $*SelectionKey "OP_ACCEPT")) +(defvar $+op-connect (jfield $*SelectionKey "OP_CONNECT")) +(defvar $+op-read (jfield $*SelectionKey "OP_READ")) +(defvar $+op-write (jfield $*SelectionKey "OP_WRITE")) + +(defconstant +java-true+ (make-immediate-object t :boolean)) +(defconstant +java-false+ (make-immediate-object nil :boolean)) ;;; Wrapper functions (return-type: java-object) (defun %get-address (address) @@ -60,6 +131,10 @@ (defun %get-by-name (string) (jstatic $@getByName/1 $*InetAddress string)) +(defun host-to-inet4 (host) + "USOCKET host formats to Java Inet4Address, used internally." + (%get-by-name (host-to-hostname host))) + ;;; HANDLE-CONTITION (defun handle-condition (condition &optional (socket nil)) @@ -79,8 +154,7 @@ (error usock-error :socket socket)))))))) (defparameter +abcl-error-map+ - `(;("java.io.IOException" . ) - ("java.net.ConnectException" . connection-refused-error) + `(("java.net.ConnectException" . connection-refused-error) ("java.net.SocketTimeoutException" . timeout-error) ("java.net.BindException" . operation-not-permitted-error))) @@ -105,11 +179,8 @@ (with-mapped-conditions () (map 'list #'get-address (%get-all-by-name name)))) -(defun host-to-inet4 (host) - "USOCKET host formats to Java Inet4Address, used internally." - (%get-by-name (host-to-hostname host))) - ;;; GET-HOST-BY-ADDRESS + (defun get-host-by-address (host) (let ((inet4 (host-to-inet4 host))) (with-mapped-conditions () @@ -120,83 +191,192 @@ (defun socket-connect (host port &key (protocol :stream) (element-type 'character) timeout deadline (nodelay t nodelay-supplied-p) local-host local-port) - (declare (type integer timeout)) - (if (eq protocol :stream) - (let* ((socket (with-mapped-conditions () - (if (or local-host local-port) - (jnew $%Socket/4 (host-to-inet4 host) port (host-to-inet4 local-host) local-port) - (if timeout - (let ((socket (jnew $%Socket/0)) - (address (jnew $%InetSocketAddress/2 (host-to-inet4 host) port))) - (jcall $@connect/2 socket address timeout) - socket) - (jnew $%Socket/2 (host-to-inet4 host) port))))) - (stream (ext:get-socket-stream socket :element-type element-type)) - (usocket (make-stream-socket :stream stream :socket socket))) - usocket) - (socket-connect-for-udp host port :timeout timeout :local-host local-host :local-port local-port))) + (when deadline (unsupported 'deadline 'socket-connect)) + (let (socket stream usocket) + (ecase protocol + (:stream ; TCP + (let ((channel (jstatic $@open/SocketChannel/0 $*SocketChannel)) + (address (jnew $%InetSocketAddress/2 (host-to-inet4 host) port))) + (setq socket (jcall $@socket/SocketChannel/0 channel)) + ;; bind to local address if needed + (when (or local-host local-port) + (let ((local-address (jnew $%InetSocketAddress/2 (host-to-inet4 local-host) (or local-port 0)))) + (with-mapped-conditions () + (jcall $@bind/Socket/1 socket local-address)))) + ;; connect to dest address + (with-mapped-conditions () + (jcall $@connect/SocketChannel/1 channel address)) + (setq stream (ext:get-socket-stream socket :element-type element-type) + usocket (make-stream-socket :stream stream :socket socket)) + (when nodelay-supplied-p + (jcall $@setTcpNoDelay/1 socket (if nodelay +java-true+ +java-false+))) + (when timeout + (jcall $@setSoTimeout/Socket/1 socket (truncate (* 1000 timeout)))))) + (:datagram ; UDP + (let ((channel (jstatic $@open/DatagramChannel/0 $*DatagramChannel))) + (setq socket (jcall $@socket/DatagramChannel/0 channel)) + ;; bind to local address if needed + (when (or local-host local-port) + (let ((local-address (jnew $%InetSocketAddress/2 (host-to-inet4 local-host) (or local-port 0)))) + (with-mapped-conditions () + (jcall $@bind/DatagramSocket/1 socket local-address)))) + ;; connect to dest address if needed + (when (and host port) + (let ((address (jnew $%InetSocketAddress/2 (host-to-inet4 host) port))) + (with-mapped-conditions () + (jcall $@connect/DatagramChannel/1 channel address)))) + (setq usocket (make-datagram-socket socket)) + (when timeout + (jcall $@setSoTimeout/DatagramSocket/1 socket (truncate (* 1000 timeout))))))) + usocket)) -(defun socket-connect-for-udp (host port &key timeout local-host local-port) - ) +;;; SOCKET-LISTEN -(defun socket-listen (host port &key reuseaddress (element-type 'character) +(defun socket-listen (host port &key (element-type 'character) (reuse-address nil reuse-address-supplied-p) (backlog 5 backlog-supplied-p)) - (let ((socket (jnew $%ServerSocket/0)) - (endpoint (jnew $%InetSocketAddress/2 (host-to-inet4 host) port))) - #+ignore ;; TODO: java.lang.IllegalArgumentException? + (declare (type boolean reuse-address)) + (let* ((channel (jstatic $@open/ServerSocketChannel/0 $*ServerSocketChannel)) + (socket (jcall $@socket/ServerSocketChannel/0 channel)) + (endpoint (jnew $%InetSocketAddress/2 (host-to-inet4 host) (or port 0)))) (when reuse-address-supplied-p - (jcall $@setReuseAddress/1 socket reuse-address)) + (jcall $@setReuseAddress/1 socket (if reuse-address +java-true+ +java-false+))) (with-mapped-conditions (socket) (if backlog-supplied-p - (jcall $@bind/2 socket endpoint backlog) - (jcall $@bind/1 socket endpoint))) + (jcall $@bind/ServerSocket/2 socket endpoint backlog) + (jcall $@bind/ServerSocket/1 socket endpoint))) (make-stream-server-socket socket :element-type element-type))) +;;; SOCKET-ACCEPT + (defmethod socket-accept ((socket stream-server-usocket) &key (element-type 'character)) (with-mapped-conditions (socket) (let* ((client-socket (jcall $@accept/0 socket)) (stream (ext:get-socket-stream client-socket :element-type element-type))) (make-stream-socket :stream stream :socket client-socket)))) +;;; SOCKET-CLOSE + (defmethod socket-close :before ((usocket usocket)) (when (wait-list usocket) (remove-waiter (wait-list usocket) usocket))) -(defmethod socket-close ((usocket usocket)) - (with-mapped-conditions (usocket) - (jcall $@close/Socket/0 (socket usocket)))) - (defmethod socket-close ((usocket stream-server-usocket)) (with-mapped-conditions (usocket) (jcall $@close/ServerSocket/0 (socket usocket)))) (defmethod socket-close ((usocket stream-usocket)) (with-mapped-conditions (usocket) - (close (socket-stream usocket)))) + (close (socket-stream usocket)) + (jcall $@close/Socket/0 (socket usocket)))) + +(defmethod socket-close ((usocket datagram-usocket)) + (with-mapped-conditions (usocket) + (jcall $@close/DatagramSocket/0 (socket usocket)))) + +;;; GET-LOCAL/PEER-NAME/ADDRESS/PORT (defmethod get-local-name ((usocket usocket)) (values (get-local-address usocket) (get-local-port usocket))) -(defmethod get-peer-name ((usocket stream-usocket)) +(defmethod get-peer-name ((usocket usocket)) (values (get-peer-address usocket) (get-peer-port usocket))) -(defmethod get-local-address ((usocket usocket)) +(defmethod get-local-address ((usocket stream-usocket)) (get-address (jcall $@getLocalAddress/Socket/0 (socket usocket)))) (defmethod get-local-address ((usocket stream-server-usocket)) (get-address (jcall $@getInetAddress/ServerSocket/0 (socket usocket)))) -(defmethod get-peer-address ((usocket usocket)) +(defmethod get-local-address ((usocket datagram-usocket)) + (get-address (jcall $@getLocalAddress/DatagramSocket/0 (socket usocket)))) + +(defmethod get-peer-address ((usocket stream-usocket)) (get-address (jcall $@getInetAddress/Socket/0 (socket usocket)))) -(defmethod get-local-port ((usocket usocket)) +(defmethod get-peer-address ((usocket datagram-usocket)) + (get-address (jcall $@getInetAddress/DatagramSocket/0 (socket usocket)))) + +(defmethod get-local-port ((usocket stream-usocket)) (jcall $@getLocalPort/Socket/0 (socket usocket))) (defmethod get-local-port ((usocket stream-server-usocket)) (jcall $@getLocalPort/ServerSocket/0 (socket usocket))) -(defmethod get-peer-port ((usocket usocket)) +(defmethod get-local-port ((usocket datagram-usocket)) + (jcall $@getLocalPort/DatagramSocket/0 (socket usocket))) + +(defmethod get-peer-port ((usocket stream-usocket)) (jcall $@getPort/Socket/0 (socket usocket))) + +(defmethod get-peer-port ((usocket datagram-usocket)) + (jcall $@getPort/DatagramSocket/0 (socket usocket))) + +;;; SOCKET-SEND & SOCKET-RECEIVE + +(defmethod socket-send ((socket datagram-usocket) buffer length &key host port) + (with-mapped-conditions (socket) + )) + +(defmethod socket-receive ((socket datagram-usocket) buffer length + &key (element-type '(unsigned-byte 8))) + (with-mapped-conditions (socket) + )) + +;;; WAIT-FOR-INPUT + +(defun socket-channel-class (usocket) + (cond ((stream-usocket-p usocket) $*SocketChannel) + ((stream-server-usocket-p usocket) $*ServerSocketChannel) + ((datagram-usocket-p usocket) $*DatagramChannel))) + +(defun get-socket-channel (usocket) + (let ((method (cond ((stream-usocket-p usocket) $@getChannel/Socket/0) + ((stream-server-usocket-p usocket) $@getChannel/ServerSocket/0) + ((datagram-usocket-p usocket) $@getChannel/DatagramSocket/0)))) + (jcall method (socket usocket)))) + +(defun wait-for-input-internal (wait-list &key timeout) + (let* ((sockets (wait-list-waiters wait-list)) + (ops (logior $+op-read $+op-accept)) + (selector (jstatic $@open/Selector/0 $*Selector)) + (channels (mapcar #'get-socket-channel sockets))) + (unwind-protect + (with-mapped-conditions () + (dolist (channel channels) + (jcall $@configureBlocking/1 channel +java-false+) + (jcall $@register/2 channel selector (logand ops (jcall $@validOps/0 channel)))) + (let ((ready-count (if timeout + (jcall $@select/1 selector (truncate (* timeout 1000))) + (jcall $@select/0 selector)))) + (when (plusp ready-count) + (let* ((keys (jcall $@selectedKeys/0 selector)) + (iterator (jcall $@iterator/0 keys)) + (%wait (wait-list-%wait wait-list))) + (loop while (jcall $@hasNext/0 iterator) + do (let* ((key (jcall $@next/0 iterator)) + (channel (jcall $@channel/0 key))) + (setf (state (gethash channel %wait)) :read))))))) + (jcall $@close/Selector/0 selector) + (dolist (channel channels) + (jcall $@configureBlocking/1 channel +java-true+))))) + +;;; WAIT-LIST + +;;; NOTE from original worker (Erik): +;;; Note that even though Java has the concept of the Selector class, which +;;; remotely looks like a wait-list, it requires the sockets to be non-blocking. +;;; usocket however doesn't make any such guarantees and is therefore unable to +;;; use the concept outside of the waiting routine itself (blergh!). + +(defun %setup-wait-list (wl) + (setf (wait-list-%wait wl) + (make-hash-table :test #'equal :rehash-size 1.3d0))) + +(defun %add-waiter (wl w) + (setf (gethash (get-socket-channel w) (wait-list-%wait wl)) w)) + +(defun %remove-waiter (wl w) + (remhash (get-socket-channel w) (wait-list-%wait wl))) Modified: usocket/trunk/package.lisp ============================================================================== --- usocket/trunk/package.lisp (original) +++ usocket/trunk/package.lisp Mon Sep 13 11:33:20 2010 @@ -5,10 +5,6 @@ (in-package :usocket-system) -#+lispworks -(eval-when (:compile-toplevel :load-toplevel :execute) - (require "comm")) - (defpackage :usocket (:use :common-lisp) (:export #:*wildcard-host* Modified: usocket/trunk/usocket.asd ============================================================================== --- usocket/trunk/usocket.asd (original) +++ usocket/trunk/usocket.asd Mon Sep 13 11:33:20 2010 @@ -23,20 +23,19 @@ :components ((:file "split-sequence") #+mcl (:file "kqueue") #+openmcl (:file "ccl-send") - #+armedbear (:file "abcl-jdi") (:file "spawn-thread"))) (:file "usocket" :depends-on ("vendor")) (:file "condition" :depends-on ("usocket")) (:module "backend" :depends-on ("condition") - :components (#+clisp (:file "clisp") + :components (#+abcl (:file "abcl") + #+clisp (:file "clisp") #+cmu (:file "cmucl") #+scl (:file "scl") #+(or sbcl ecl) (:file "sbcl") #+lispworks (:file "lispworks") #+mcl (:file "mcl") #+openmcl (:file "openmcl") - #+allegro (:file "allegro") - #+armedbear (:file "armedbear"))) + #+allegro (:file "allegro"))) (:file "server" :depends-on ("backend")))) (defmethod perform ((op test-op) (c (eql (find-system :usocket)))) Modified: usocket/trunk/usocket.lisp ============================================================================== --- usocket/trunk/usocket.lisp (original) +++ usocket/trunk/usocket.lisp Mon Sep 13 11:33:20 2010 @@ -431,7 +431,8 @@ ((or (vector t 4) (array (unsigned-byte 8) (4))) (vector-quad-to-dotted-quad host)) - (integer (hbo-to-dotted-quad host)))) + (integer (hbo-to-dotted-quad host)) + (null "0.0.0.0"))) (defun ip= (ip1 ip2) (etypecase ip1 @@ -452,7 +453,7 @@ ;; DNS helper functions ;; -#-(or clisp armedbear) +#-clisp (progn (defun get-host-by-name (name) (let ((hosts (get-hosts-by-name name))) From ctian at common-lisp.net Tue Sep 14 08:07:21 2010 From: ctian at common-lisp.net (Chun Tian (binghe)) Date: Tue, 14 Sep 2010 04:07:21 -0400 Subject: [usocket-cvs] r556 - in usocket/trunk: . backend Message-ID: Author: ctian Date: Tue Sep 14 04:07:20 2010 New Revision: 556 Log: ABCL: basically working implementation of SOCKET-SEND/SOCKET-RECEIVE. Modified: usocket/trunk/README usocket/trunk/backend/abcl.lisp usocket/trunk/package.lisp usocket/trunk/usocket.lisp Modified: usocket/trunk/README ============================================================================== --- usocket/trunk/README (original) +++ usocket/trunk/README Tue Sep 14 04:07:20 2010 @@ -22,14 +22,14 @@ - SBCL - CMUCL - - ArmedBear (post feb 11th, 2006 CVS or 0.0.10 and higher) - - clisp + - ArmedBear Common Lisp + - GNU CLISP - Allegro Common Lisp - LispWorks - - OpenMCL + - Clozure CL - ECL - Scieneer Common Lisp - - + - Macintosh Common Lisp If your favorite common lisp misses in the list above, please contact usocket-devel at common-lisp.net and submit a request. Please include Modified: usocket/trunk/backend/abcl.lisp ============================================================================== --- usocket/trunk/backend/abcl.lisp (original) +++ usocket/trunk/backend/abcl.lisp Tue Sep 14 04:07:20 2010 @@ -8,29 +8,15 @@ (in-package :usocket) -;;; Symbols in JAVA package -(eval-when (:compile-toplevel :load-toplevel :execute) - (defparameter *java-package-symbols* - '(java:jarray-length - java:jarray-ref - java:java-exception - java:java-exception-cause - java:jconstructor - java:jcall - java:jclass - java:jclass-of - java:jfield - java:jmethod - java:jnew - java:jstatic - java:make-immediate-object)) - (import *java-package-symbols*)) - ;;; Java Classes ($*...) (defvar $*boolean (jclass "boolean")) +(defvar $*byte (jclass "byte")) +(defvar $*byte[] (jclass "[B")) (defvar $*int (jclass "int")) (defvar $*long (jclass "long")) +(defvar $*|Byte| (jclass "java.lang.Byte")) (defvar $*DatagramChannel (jclass "java.nio.channels.DatagramChannel")) +(defvar $*DatagramPacket (jclass "java.net.DatagramPacket")) (defvar $*DatagramSocket (jclass "java.net.DatagramSocket")) (defvar $*Inet4Address (jclass "java.net.Inet4Address")) (defvar $*InetAddress (jclass "java.net.InetAddress")) @@ -48,6 +34,9 @@ (defvar $*String (jclass "java.lang.String")) ;;; Java Constructor ($%.../n) +(defvar $%Byte/0 (jconstructor $*|Byte| $*byte)) +(defvar $%DatagramPacket/3 (jconstructor $*DatagramPacket $*byte[] $*int $*int)) +(defvar $%DatagramPacket/5 (jconstructor $*DatagramPacket $*byte[] $*int $*int $*InetAddress $*int)) (defvar $%DatagramSocket/0 (jconstructor $*DatagramSocket)) (defvar $%DatagramSocket/1 (jconstructor $*DatagramSocket $*int)) (defvar $%DatagramSocket/2 (jconstructor $*DatagramSocket $*int $*InetAddress)) @@ -67,6 +56,7 @@ (defvar $@bind/ServerSocket/1 (jmethod $*ServerSocket "bind" $*SocketAddress)) (defvar $@bind/ServerSocket/2 (jmethod $*ServerSocket "bind" $*SocketAddress $*int)) (defvar $@bind/Socket/1 (jmethod $*Socket "bind" $*SocketAddress)) +(defvar $@byteValue/0 (jmethod $*|Byte| "byteValue")) (defvar $@channel/0 (jmethod $*SelectionKey "channel")) (defvar $@close/DatagramSocket/0 (jmethod $*DatagramSocket "close")) (defvar $@close/Selector/0 (jmethod $*Selector "close")) @@ -83,15 +73,19 @@ (defvar $@getChannel/DatagramSocket/0 (jmethod $*DatagramSocket "getChannel")) (defvar $@getChannel/ServerSocket/0 (jmethod $*ServerSocket "getChannel")) (defvar $@getChannel/Socket/0 (jmethod $*Socket "getChannel")) +(defvar $@getAddress/DatagramPacket/0 (jmethod $*DatagramPacket "getAddress")) (defvar $@getHostName/0 (jmethod $*InetAddress "getHostName")) (defvar $@getInetAddress/DatagramSocket/0 (jmethod $*DatagramSocket "getInetAddress")) (defvar $@getInetAddress/ServerSocket/0 (jmethod $*ServerSocket "getInetAddress")) (defvar $@getInetAddress/Socket/0 (jmethod $*Socket "getInetAddress")) +(defvar $@getLength/DatagramPacket/0 (jmethod $*DatagramPacket "getLength")) (defvar $@getLocalAddress/DatagramSocket/0 (jmethod $*DatagramSocket "getLocalAddress")) (defvar $@getLocalAddress/Socket/0 (jmethod $*Socket "getLocalAddress")) (defvar $@getLocalPort/DatagramSocket/0 (jmethod $*DatagramSocket "getLocalPort")) (defvar $@getLocalPort/ServerSocket/0 (jmethod $*ServerSocket "getLocalPort")) (defvar $@getLocalPort/Socket/0 (jmethod $*Socket "getLocalPort")) +(defvar $@getOffset/DatagramPacket/0 (jmethod $*DatagramPacket "getOffset")) +(defvar $@getPort/DatagramPacket/0 (jmethod $*DatagramPacket "getPort")) (defvar $@getPort/DatagramSocket/0 (jmethod $*DatagramSocket "getPort")) (defvar $@getPort/Socket/0 (jmethod $*Socket "getPort")) (defvar $@hasNext/0 (jmethod $*Iterator "hasNext")) @@ -101,10 +95,12 @@ (defvar $@open/Selector/0 (jmethod $*Selector "open")) (defvar $@open/ServerSocketChannel/0 (jmethod $*ServerSocketChannel "open")) (defvar $@open/SocketChannel/0 (jmethod $*SocketChannel "open")) +(defvar $@receive/1 (jmethod $*DatagramSocket "receive" $*DatagramPacket)) (defvar $@register/2 (jmethod $*SelectableChannel "register" $*Selector $*int)) (defvar $@select/0 (jmethod $*Selector "select")) (defvar $@select/1 (jmethod $*Selector "select" $*long)) (defvar $@selectedKeys/0 (jmethod $*Selector "selectedKeys")) +(defvar $@send/1 (jmethod $*DatagramSocket "send" $*DatagramPacket)) (defvar $@setReuseAddress/1 (jmethod $*ServerSocket "setReuseAddress" $*boolean)) (defvar $@setSoTimeout/DatagramSocket/1 (jmethod $*DatagramSocket "setSoTimeout" $*int)) (defvar $@setSoTimeout/Socket/1 (jmethod $*Socket "setSoTimeout" $*int)) @@ -137,6 +133,18 @@ ;;; HANDLE-CONTITION +(defparameter +abcl-error-map+ + `(("java.net.BindException" . operation-not-permitted-error) + ("java.net.ConnectException" . connection-refused-error) + ("java.net.NoRouteToHostException" . network-unreachable-error) ; untested + ("java.net.PortUnreachableException" . protocol-not-supported-error) ; untested + ("java.net.ProtocolException" . protocol-not-supported-error) ; untested + ("java.net.SocketException" . socket-type-not-supported-error) ; untested + ("java.net.SocketTimeoutException" . timeout-error))) + +(defparameter +abcl-nameserver-error-map+ + `(("java.net.UnknownHostException" . ns-host-not-found-error))) + (defun handle-condition (condition &optional (socket nil)) (typecase condition (java-exception @@ -153,27 +161,18 @@ (when usock-error (error usock-error :socket socket)))))))) -(defparameter +abcl-error-map+ - `(("java.net.ConnectException" . connection-refused-error) - ("java.net.SocketTimeoutException" . timeout-error) - ("java.net.BindException" . operation-not-permitted-error))) - -(defparameter +abcl-nameserver-error-map+ - `(("java.net.UnknownHostException" . ns-host-not-found-error))) - ;;; GET-HOSTS-BY-NAME (defun get-address (address) - (let* ((array (%get-address address)) - (length (jarray-length array))) - (labels ((jbyte (n) - (let ((byte (jarray-ref array n))) - (if (plusp byte) - byte - (+ 256 byte))))) - (if (= 4 length) - (vector (jbyte 0) (jbyte 1) (jbyte 2) (jbyte 3)) - nil)))) ; not a IPv4 address?! + (when address + (let* ((array (%get-address address)) + (length (jarray-length array))) + (labels ((jbyte (n) + (let ((byte (jarray-ref array n))) + (if (minusp byte) (+ 256 byte) byte)))) + (if (= 4 length) + (vector (jbyte 0) (jbyte 1) (jbyte 2) (jbyte 3)) + nil))))) ; not a IPv4 address?! (defun get-hosts-by-name (name) (with-mapped-conditions () @@ -225,7 +224,7 @@ (let ((address (jnew $%InetSocketAddress/2 (host-to-inet4 host) port))) (with-mapped-conditions () (jcall $@connect/DatagramChannel/1 channel address)))) - (setq usocket (make-datagram-socket socket)) + (setq usocket (make-datagram-socket socket :connected-p (if (and host port) t nil))) (when timeout (jcall $@setSoTimeout/DatagramSocket/1 socket (truncate (* 1000 timeout))))))) usocket)) @@ -316,14 +315,54 @@ ;;; SOCKET-SEND & SOCKET-RECEIVE -(defmethod socket-send ((socket datagram-usocket) buffer length &key host port) - (with-mapped-conditions (socket) - )) +(defun *->byte (data) + (declare (type (unsigned-byte 8) data)) ; required by SOCKET-SEND + (jnew $%Byte/0 (if (> data 127) (- data 256) data))) + +(defun byte->* (byte &optional (element-type '(unsigned-byte 8))) + (let* ((ub8 (if (minusp byte) (+ 256 byte) byte))) + (if (eq element-type 'character) + (code-char ub8) + ub8))) + +(defmethod socket-send ((usocket datagram-usocket) buffer length &key host port) + (let* ((socket (socket usocket)) + (real-length (or length (length buffer))) + (byte-array (jnew-array $*byte real-length)) + (packet (if (and host port) + (jnew $%DatagramPacket/5 byte-array 0 real-length (host-to-inet4 host) port) + (jnew $%DatagramPacket/3 byte-array 0 real-length)))) + ;; prepare sending data + (loop for i from 0 below real-length + do (setf (jarray-ref byte-array i) (*->byte (aref buffer i)))) + (with-mapped-conditions (usocket) + (jcall $@send/1 socket packet)) + real-length)) -(defmethod socket-receive ((socket datagram-usocket) buffer length +;;; TODO: return-host and return-port cannot be get ... +(defmethod socket-receive ((usocket datagram-usocket) buffer length &key (element-type '(unsigned-byte 8))) - (with-mapped-conditions (socket) - )) + (let* ((socket (socket usocket)) + (real-length (or length +max-datagram-packet-size+)) + (byte-array (jnew-array $*byte real-length)) + (packet (jnew $%DatagramPacket/3 byte-array 0 real-length))) + (with-mapped-conditions (usocket) + (jcall $@receive/1 socket packet)) + (let* ((receive-length (jcall $@getLength/DatagramPacket/0 packet)) + (return-buffer (or buffer (make-array receive-length :element-type element-type)))) + (loop for i from 0 below receive-length + do (setf (aref return-buffer i) + (byte->* (jarray-ref byte-array i) element-type))) + (let ((return-host (if (connected-p usocket) + (get-peer-address usocket) + (get-address (jcall $@getAddress/DatagramPacket/0 packet)))) + (return-port (if (connected-p usocket) + (get-peer-port usocket) + (jcall $@getPort/DatagramPacket/0 packet)))) + (values return-buffer + receive-length + return-host + return-port))))) ;;; WAIT-FOR-INPUT Modified: usocket/trunk/package.lisp ============================================================================== --- usocket/trunk/package.lisp (original) +++ usocket/trunk/package.lisp Tue Sep 14 04:07:20 2010 @@ -6,7 +6,7 @@ (in-package :usocket-system) (defpackage :usocket - (:use :common-lisp) + (:use :common-lisp #+abcl :java) (:export #:*wildcard-host* #:*auto-port* Modified: usocket/trunk/usocket.lisp ============================================================================== --- usocket/trunk/usocket.lisp (original) +++ usocket/trunk/usocket.lisp Tue Sep 14 04:07:20 2010 @@ -11,7 +11,7 @@ (defparameter *auto-port* 0 "Port number to pass when an auto-assigned port number is wanted.") -(defconstant +max-datagram-packet-size+ 65536) +(defconstant +max-datagram-packet-size+ 65507) (defclass usocket () ((socket From ctian at common-lisp.net Tue Sep 14 17:37:37 2010 From: ctian at common-lisp.net (Chun Tian (binghe)) Date: Tue, 14 Sep 2010 13:37:37 -0400 Subject: [usocket-cvs] r557 - public_html Message-ID: Author: ctian Date: Tue Sep 14 13:37:36 2010 New Revision: 557 Log: Updated USOCKET Web Documents Modified: public_html/api-docs.shtml Modified: public_html/api-docs.shtml ============================================================================== --- public_html/api-docs.shtml (original) +++ public_html/api-docs.shtml Tue Sep 14 13:37:36 2010 @@ -1,11 +1,10 @@ - - - + + usocket API documentation - - + + - -

usocket API documentation

- -

$Id$
- Work in progress.

- +

$Id: api-docs.shtml 417 2008-08-07 20:29:51Z +ehuelsmann $
+Work in progress.

Please note that we're committed to the interface described -below for the entire 0.x phase of the library. When 1.0 comes +below for the entire 0.x phase of the library. When 1.0 comes some of the functionality may be split up in different functions and guarantees may change because of it.

- -

Conventions

- -
-
Specification of a host parameter
-
A host parameter may be any one of +
Specification of a host parameter
+
A host parameter may be any one of
    -
  • 32-bit positive integer,
  • -
  • a string containing an IP addres in dotted notation, or
  • -
  • a host name to be resolved through DNS lookup.
  • +
  • 32-bit positive integer,
  • +
  • a string containing an IP addres in dotted notation, or
  • +
  • a host name to be resolved through DNS lookup.
-
+
-

Functions for socket creation and manipulation

-
-
socket-connect host port &key element-type => socket
+
socket-connect +host port &key protocol element-type timeout deadline nodelay +local-host local-port => socket
+
+

Creates a TCP (stream) or UDP (datagram) socket to the host +and port specified. The return value is +a socket object of class stream-usocket, +or -

-

Creates a tcp (stream) socket to the host and port specified. The return value is -a socket object of class stream-usocket.

- -

The element-type argument is used in the -construction of the associated stream.

- -
-socket-listen host port &key reuse-address backlog element-type => socket
-

Creates and returns a passive ("server") socket associated with host and port. - The object returned is of subtype stream-server-usocket.

-

host names a local interface.
- port names a local port, or 0 (zero) to request a random free port.
- reuse-address is a boolean (t, nil) value signalling reuse of the address is requested (or not).
- backlog is the length of the queue containing connections which haven't actually been accepted yet.
- element-type is the default element type used for sockets created by socket-accept. character is - the default when it's not explicitly provided. -

- - -
socket-accept socket &key element-type => new-socket
-

Creates and returns an active ("connected") stream socket new-socket from the - socket passed. The return value is a socket object of class - stream-usocket.

-

element-type is the element type used to construct the associated stream. If it's not specified, - the element-type of socket (as used when it was created by the call to socket-listen) is - used. + + + datagram-usocket.

+

protocol should be :stream (default) or :datagram, +which +means +TCP +or +UDP. (Start from USOCKET 0.5)
+ element-type argument is used in the +construction of the associated stream, i.e. 'character or + '(unsigned-byte 8), only used by TCP.
+ timeout is a integer, it represents the socket option SO_RCVTIMEO +(read timeout), in seconds.
+ deadline is only supported in Clozure CL and Digitool MCL, +look up their documents please.
+ local-host and local-port, when specified, will +cause the socket calling bind() on local address. This is useful for +selecting interfaces to send, or listening on UDP port. Note: use only +one of them are allowed when reasonable (listen on wildcard address, or +bind to random free port).
+
+

+
+
socket-listen +host port &key reuse-address backlog element-type => socket
+
+

Creates and returns a passive ("server") socket associated with host +and port. The object returned is of subtype stream-server-usocket.

+

host names a local interface.
+ port names a local port, or 0 (zero) to request a random +free port.
+ reuse-address is a boolean (t, nil) value signalling reuse +of the address is requested (or not).
+ backlog is the length of the queue containing connections +which haven't actually been accepted yet.
+ element-type is the default element type used for sockets +created by socket-accept. character is the default when it's +not explicitly provided.

+
+
socket-accept +socket &key element-type => new-socket
+
+

Creates and returns an active ("connected") stream socket new-socket +from the socket passed. The return value is a socket object +of class stream-usocket.

+

element-type is the element type used to construct the +associated stream. If it's not specified, the element-type of socket +(as used when it was created by the call to socket-listen) is used.

+
+
socket-close +socket
+
+

Flushes the stream associated with the socket and closes the +socket connection.

+
+
get-local-name +socket => address, port
+ get-local-address +socket => address
+ get-local-port +socket => port
+
+

Returns the local address and/or port information of socket.

+
+
get-peer-name +socket => address, port
+ get-peer-address +socket => address
+ get-peer-port +socket => port
+
+

Returns the remote address and/or port information of socket. +The socket passed to this function must be a connected socket.

+
+
socket-send +socket buffer length &key host port
+
+
+

Send a (unsigned-byte 8) data buffer to a datagram socket, and +return the number of bytes sent. (Start from USOCKET 0.5)

+

socket should be a datagram-usocket.
+ buffer is a Lisp vector, type of (simple-array +(unsigned-byte 8) *).
+ length is used to tell socket-send +the actual useful length of data buffer for sending to socket.
+ host and port are used for unconnected datagram +sockets, for sending to specific destination.

-
+ +
socket-receive +socket buffer length
+
+
+

Receive data from a datagram socket, and return 4 values: return-buffer, -

socket-close socket
-

Flushes the stream associated with the socket and closes the socket connection.

-
get-local-name socket => address, port
-get-local-name socket => address
-get-local-port socket => port
-

Returns the local address and/or port information of socket.

- -
get-peer-name socket => address, port
-get-peer-name socket => address
-get-peer-port socket => port
-

Returns the remote address and/or port information of socket. - The socket passed to this function must be a connected socket.

+ return-length, remote-host, and remove-port. +If +the +datagram +socket +was created by socket-connect +with a timeout keyword argument, this function will block at +most that timeout value (in seconds). (Start from USOCKET 0.5)

+

socket should be a datagram-usocket.
+ buffer is a Lisp vector, type of (simple-array +(unsigned-byte 8) *). Using nil here is also +allowed, new buffer will be created to hold data.
+ length is used to specify the length of a exist buffer for +receiving at most these data. Using nil here is allowed, and +the actual length of buffer will be used; when buffer +is also nil, a default maximum length (65507) will be +used.
+

+ +
wait-for-input +socket-or-sockets &key timeout ready-only
+
+
+

Waiting on one or multiple sockets for given time, and returns +once some of them are available of reading data. This is like UNIX's +"select" function.
+
+It returns two values: the first is the list of sockets which are +readable (or in case of server sockets acceptable). nil may be returned +for this value either when waiting timed out or when it was interrupted +(EINTR).  The second value is a real number indicating the time +remaining within the timeout period or nil if none.
+
+Without the READY-ONLY arg, WAIT-FOR-INPUT will return all sockets in +the original list you passed it. This prevents a new list from being +consed up. Some users of USOCKET were reluctant to use it if it +wouldn't behave that way, expecting it to cost significant performance +to do the associated garbage collection.
+
+Without the READY-ONLY arg, you need to check the socket STATE slot for +the values documented in usocket.lisp in the usocket class.
+

+
+
socket-server +host port function &optional arguments &key in-new-thread +protocol timeout max-buffer-size element-type reuse-address +multi-threading
+
+
+

Create a simple TCP or UDP socket server ... (Start from USOCKET +0.5)

+
-

Classes

-
usocket
Slots:
-
socket :accessor socket
-

Used to store sockets as used by the current implementation - may be any of socket handles, socket objects and stream objects

+
socket :accessor socket
+
+
+

Used to store sockets as used by the current implementation +- may be any of socket handles, socket objects and stream objects

+
+
state :accessor state
+
+
+

Used to store socket state: NIL (not ready), :READ (ready to +read).
+

+
+
- -
stream-usocket
-
Parent classes: usocket
- Slots: +
stream-usocket
+
Parent classes: usocket
+Slots: +
+
stream :accessor socket-stream
+
+

Used to store the stream associated with the tcp socket +connection.
+When you want to write to the socket stream, use this function.

+
+
+
+
stream-server-usocket
+
Parent classes: usocket
+Slots:
-
stream :accessor socket-stream
-

Used to store the stream associated with the tcp socket connection.
- When you want to write to the socket stream, use this function.

-
- -
stream-server-usocket
-
Parent classes: usocket
- Slots: +
element-type :reader +element-type
+
+

Indicates the default element-type to be used when +constructing streams off this socket when no element type is specified +in the call to socket-accept.

+
+ + +
datagram-usocket +(Start from USOCKET 0.5)
+
+
Parent classes: usocket
+Slots:
-
element-type :reader element-type
-

Indicates the default element-type to be used when constructing streams off this socket when - no element type is specified in the call to socket-accept.

-
+
connected-p :accessor +connected-p
+
+

Used to identify if the datagram is connected. It will be +setup by socket-connect, and +used by socket-send and socket-receive.

+
+ + -

Variables / constants

-
-
*wildcard-host*
-

The host to use with socket-listen to make the socket listen on all available interfaces.

-
*auto-port*
-

The port number to use with socket-listen to make the socket listen on a random available port. The port number assigned can be - retrieved from the returned socket by calling get-local-port.

+
*wildcard-host*
+
+

The host to use with socket-listen +to make the socket listen on all available interfaces.

+
+
*auto-port*
+
+

The port number to use with socket-listen to make the socket +listen on a random available port. The port number assigned can be +retrieved from the returned socket by calling get-local-port.

+
+
*remote-host*
+
+

Special variable used in socket-server's +handler function for getting current client address. (Start from +USOCKET 0.5)
+

+
+
*remote-port*
+
+

Special variable used in socket-server's +handler function for getting current client port. (Start from USOCKET +0.5)

+
- -

How do I ...

-
-
... force the output to be written to the network? -
-
When you write output to the stream, it may be buffered before - sent over the network - for optimal performance of small writes. You - can force the buffer to be flushed the same way as with normal streams: - -
(format (socket-stream socket) "Hello there~%")   ;; output into buffers
-(force-output (socket-stream socket))             ;; <== flush the buffers, if any
-
-
-
... check whether the other end has closed my socket stream? -
-
Reading from a stream which has been closed at the remote end - signals an END-OF-FILE condition, meaning that reading from the stream - and detecting that condition is the way to do it. -
-
... check whether reading from a socket stream will block? -
-
When you want to check one stream for readiness of input, - call the - listen - function on the stream object associated with the socket.
- Example: -
(listen (usocket:socket-stream your-socket))
- ==> NIL (if no input is available)
-
-
-
... wait for input to become available on (at least) one stream (of a set) -
-
Currently, that's hard to do efficiently if you want to use releases. - The next minor release (0.4.0) will include this functionality and - for all platforms (except SBCL and LispWorks; both Win32) it's already - available in trunk (svn://common-lisp.net/project/usocket/svn/usocket/trunk). -
- If you want to use this code you're most welcome and feedback is appreciated.
- Example to be used with trunk: -
(usocket:wait-for-input (list socket1 socket2 socket3) :timeout <your optional timeout value>)
- ==> list-of-sockets-to-read-from
-
-
... convert my existing trivial-sockets based application to usocket? -
-
There are actually 3 answers to that question. -
    -
  1. Rewrite your code to keep a usocket object instead of the stream - object returned by trivial-sockets.
  2. -
  3. The quick conversion with the good performance characteristics - (use only when you don't want to use the socket object):
    - Replace all your invocations of -
    -  (trivial-sockets:open-socket-stream ....)
    -
    -with
    -  (usocket:socket-stream (usocket:socket-connect ...))
    -
    - +
    ... force the output to be written to the network?
    +
    When you write output to the stream, it may be buffered before +sent over the network - for optimal performance of small writes. You +can force the buffer to be flushed the same way as with normal streams: +
    (format (socket-stream socket) "Hello there~%")   ;; output into buffers
    (force-output (socket-stream socket)) ;; <== flush the buffers, if any
    +
    +
    ... check whether the other end has closed my socket stream?
    +
    Reading from a stream which has been closed at the remote end +signals an END-OF-FILE condition, meaning that reading from the stream +and detecting that condition is the way to do it.
    +
    ... check whether reading from a socket stream will block?
    +
    When you want to check one stream for readiness of input, +call the listen +function on the stream object associated with the socket.
    +Example: +
    (listen (usocket:socket-stream your-socket))
    ==> NIL (if no input is available)
    +
    +
    ... wait for input to become available on (at least) one stream +(of a set)
    +
    Currently, that's hard to do efficiently if you want to use +releases. The next minor release (0.4.0) will include this +functionality and for all platforms (except SBCL and LispWorks; both +Win32) it's already available in trunk +(svn://common-lisp.net/project/usocket/svn/usocket/trunk).
    +If you want to use this code you're most welcome and feedback is +appreciated.
    +Example to be used with trunk: +
    (usocket:wait-for-input (list socket1 socket2 socket3) :timeout <your optional timeout value>)
    ==> list-of-sockets-to-read-from
    +
    +
    ... convert my existing trivial-sockets based application to +usocket?
    +
    There are actually 3 answers to that question. +
      +
    1. Rewrite your code to keep a usocket object instead of the +stream object returned by trivial-sockets.
    2. +
    3. The quick conversion with the good performance +characteristics (use only when you don't want to use the socket object):
      +Replace all your invocations of +
        (trivial-sockets:open-socket-stream ....)

      with
      (usocket:socket-stream (usocket:socket-connect ...))
      And replace all invocations of -
      -  (trivial-sockets:socket-accept ...)
      -
      -with
      -  (usocket:socket-stream (usocket:socket-accept ...))
      -
      - +
        (trivial-sockets:socket-accept ...)

      with
      (usocket:socket-stream (usocket:socket-accept ...))
      And replace all invocations of -
      -  (trivial-sockets:open-server ...)
      -
      -with
      -  (usocket:socket-listen ...)
      -
    4. -
    5. And the last option which provides a compatible - (but slower, because it uses Gray streams) interface is to use - trivial-usocket.
      - The trivial-usocket package provides a 1-1 mapped interface to - trivial-sockets, but uses Gray streams; that way, it's later possible - to retrieve the socket object from the stream returned and to use that - socket for other usocket operations. Use this approach as a migration - path where you're not rewriting your application at once, but in - small steps. +
        (trivial-sockets:open-server ...)

      with
      (usocket:socket-listen ...)
    6. +
    7. And the last option which provides a compatible (but slower, +because it uses Gray streams) interface is to use trivial-usocket.
      +The trivial-usocket package provides a 1-1 mapped interface to +trivial-sockets, but uses Gray streams; that way, it's later possible +to retrieve the socket object from the stream returned and to use that +socket for other usocket operations. Use this approach as a migration +path where you're not rewriting your application at once, but in small +steps.
    -
    - +
- - -
+
Back to Common-lisp.net.
- + From ctian at common-lisp.net Wed Sep 15 03:35:30 2010 From: ctian at common-lisp.net (Chun Tian (binghe)) Date: Tue, 14 Sep 2010 23:35:30 -0400 Subject: [usocket-cvs] r558 - public_html Message-ID: Author: ctian Date: Tue Sep 14 23:35:27 2010 New Revision: 558 Log: API documentation for SOCKET-SERVER was added. Modified: public_html/api-docs.shtml Modified: public_html/api-docs.shtml ============================================================================== --- public_html/api-docs.shtml (original) +++ public_html/api-docs.shtml Tue Sep 14 23:35:27 2010 @@ -1,7 +1,7 @@ - + - usocket API documentation + USOCKET API documentation @@ -34,9 +34,8 @@
  • API documentation
  • How do I ... (FAQ)
  • -

    usocket API documentation

    -

    $Id: api-docs.shtml 417 2008-08-07 20:29:51Z -ehuelsmann $
    +

    USOCKET API documentation

    +

    $Id$
    Work in progress.

    Please note that we're committed to the interface described below for the entire 0.x phase of the library. When 1.0 comes @@ -44,10 +43,15 @@ and guarantees may change because of it.

    Conventions

    -
    Specification of a host parameter
    -
    A host parameter may be any one of +
    Specification of a host or local-host +parameter
    +
    A host or local-host parameter may be any one +of
    • 32-bit positive integer,
    • +
    • A four element integer list representing IPv4 address, i.e. +#(127 0 0 1)
      +
    • a string containing an IP addres in dotted notation, or
    • a host name to be resolved through DNS lookup.
    @@ -63,16 +67,13 @@ and port specified. The return value is a socket object of class stream-usocket, or - - - datagram-usocket.

    protocol should be :stream (default) or :datagram, which means TCP or -UDP. (Start from USOCKET 0.5)
    +UDP (Start from USOCKET 0.5)
    element-type argument is used in the construction of the associated stream, i.e. 'character or '(unsigned-byte 8), only used by TCP.
    @@ -169,7 +170,13 @@ the datagram socket -was created by socket-connect +was +created +by + + + + socket-connect with a timeout keyword argument, this function will block at most that timeout value (in seconds). (Start from USOCKET 0.5)

    socket should be a datagram-usocket.
    @@ -197,14 +204,16 @@ (EINTR).  The second value is a real number indicating the time remaining within the timeout period or nil if none.

    -Without the READY-ONLY arg, WAIT-FOR-INPUT will return all sockets in +Without the ready-only argument, WAIT-FOR-INPUT will return +all sockets in the original list you passed it. This prevents a new list from being consed up. Some users of USOCKET were reluctant to use it if it wouldn't behave that way, expecting it to cost significant performance to do the associated garbage collection.

    -Without the READY-ONLY arg, you need to check the socket STATE slot for -the values documented in usocket.lisp in the usocket class.
    +Without the ready-only arg, you need to check the socket +STATE slot for +the values documented in usocket class.

    socket-server @@ -213,8 +222,58 @@ multi-threading
    -

    Create a simple TCP or UDP socket server ... (Start from USOCKET -0.5)

    +

    Create a simple TCP or UDP socket server. (Start from USOCKET +0.5)
    +

    +

    host names a local interface,
    + port names a local port,
    + function names a function object, which is used to handle +TCP or UDP connections, the actual API of this function will be +explained later.
    + arguments is a list used for passing extra arguments to +user-defined function.
    + in-new-thread is a boolean, default is nil. +When it's T, the server will be created in a new thread +and socket-server returns immediately in current thread.
    + protocol could be either :stream (default) +or :datagram, which decide the socket server is TCP +server or UDP server.
    + timeout is UDP only, it provides the internal socket-receive call (in UDP event +loop of the socket server) a read timeout, default value is 1 (second).
    + max-buffer-size is UDP only, it's the max UDP data buffer +size when handling UDP packets, default value is 65507.
    + element-type is TCP only, it's element-type of the stream +provided for user-defined function,
    + reuse-address is TCP only, it's a boolean option for +internal call of socket-listen in the socket server,
    + multi-threading is TCP only, it's a boolean, default value +is nil. When it's T, each client connection +will cause a new thread being created to handle that client, so that +the TCP server could handle multiple clients at the same time. (Note: +since UDP server is connectionless, it can always handle multiple +clients, as long as the handler function run fast enough)
    +

    +

    The handler function for TCP is stream-based. A template +function +is this one:

    +
    (defun default-tcp-handler (stream) ; null
    (declare (type stream stream))
    (terpri stream))
    +

    Note: 1. you don't need to close the stream as socket-server +will do that for you. +2. More function arguments can be defined, and these extra arguments +must be feeded as the optional arguments of socket-server.

    +

    The handler function for UDP is buffer-based, that is, +you receive a buffer of data as input, and you return another buffer +for output. A template function is a simple UDP echo server:

    +
    (defun default-udp-handler (buffer) ; echo
    (declare (type (simple-array (unsigned-byte 8) *) buffer))
    buffer)
    +

    Note: 1. data length is the length of the whole buffer. 2. +Sometimes you may want to know the client's IP address and sending +port, these informations are specially bounded on variables + *remote-host* and *remote-port* when handler function +is running.

    Classes

    @@ -264,7 +323,10 @@
    datagram-usocket -(Start from USOCKET 0.5)
    +(Start +from +USOCKET +0.5)
    Parent classes: usocket
    Slots: @@ -294,17 +356,29 @@ retrieved from the returned socket by calling get-local-port.

    -
    *remote-host*
    +
    *remote-host*

    Special variable used in socket-server's -handler function for getting current client address. (Start from +handler +function +for +getting +current +client +address. (Start from USOCKET 0.5)

    -
    *remote-port*
    +
    *remote-port*

    Special variable used in socket-server's -handler function for getting current client port. (Start from USOCKET +handler +function +for +getting +current +client +port. (Start from USOCKET 0.5)

    From ctian at common-lisp.net Wed Sep 15 04:19:02 2010 From: ctian at common-lisp.net (Chun Tian (binghe)) Date: Wed, 15 Sep 2010 00:19:02 -0400 Subject: [usocket-cvs] r560 - in usocket/trunk: . backend Message-ID: Author: ctian Date: Wed Sep 15 00:19:01 2010 New Revision: 560 Log: Fixed legacy reuseaddress argument for MCL and ABCL; Add CHANGES; Update TODO. Added: usocket/trunk/CHANGES Modified: usocket/trunk/TODO usocket/trunk/backend/abcl.lisp usocket/trunk/backend/mcl.lisp usocket/trunk/usocket-test.asd Added: usocket/trunk/CHANGES ============================================================================== --- (empty file) +++ usocket/trunk/CHANGES Wed Sep 15 00:19:01 2010 @@ -0,0 +1,7 @@ +0.5.0: + +* New supported platform: Macintosh Common Lisp (5.0 and up, plus RMCL) +* Support for UDP (datagram-usocket) was added (for all supported platform except MCL) +* Add WAIT-FOR-INPUT support for SBCL and ECL on win32. +* Simple TCP and UDP server API: SOCKET-SERVER +* Lots of bug fixed since 0.4.1 Modified: usocket/trunk/TODO ============================================================================== --- usocket/trunk/TODO (original) +++ usocket/trunk/TODO Wed Sep 15 00:19:01 2010 @@ -1,17 +1,4 @@ - -- Implement wait-for-input-internal for - * SBCL Win32 - -- Implement errors for (the alien interface code of) - * SBCL Unix - * CMUCL Unix - * OpenMCL - - -- Extend ABCL socket support with the 4 java errors in java.net.* - so that they can map to our usocket errors instead of mapping - all errors to unknown-error. - +- Fix condition systems (make all implementation generate same error) - Add INET6 support. For more TODO items, see http://trac.common-lisp.net/usocket/report. Modified: usocket/trunk/backend/abcl.lisp ============================================================================== --- usocket/trunk/backend/abcl.lisp (original) +++ usocket/trunk/backend/abcl.lisp Wed Sep 15 00:19:01 2010 @@ -231,15 +231,16 @@ ;;; SOCKET-LISTEN -(defun socket-listen (host port &key (element-type 'character) +(defun socket-listen (host port &key reuseaddress (reuse-address nil reuse-address-supplied-p) - (backlog 5 backlog-supplied-p)) + (backlog 5 backlog-supplied-p) + (element-type 'character)) (declare (type boolean reuse-address)) - (let* ((channel (jstatic $@open/ServerSocketChannel/0 $*ServerSocketChannel)) + (let* ((reuseaddress (if reuse-address-supplied-p reuse-address reuseaddress)) + (channel (jstatic $@open/ServerSocketChannel/0 $*ServerSocketChannel)) (socket (jcall $@socket/ServerSocketChannel/0 channel)) (endpoint (jnew $%InetSocketAddress/2 (host-to-inet4 host) (or port 0)))) - (when reuse-address-supplied-p - (jcall $@setReuseAddress/1 socket (if reuse-address +java-true+ +java-false+))) + (jcall $@setReuseAddress/1 socket (if reuseaddress +java-true+ +java-false+)) (with-mapped-conditions (socket) (if backlog-supplied-p (jcall $@bind/ServerSocket/2 socket endpoint backlog) Modified: usocket/trunk/backend/mcl.lisp ============================================================================== --- usocket/trunk/backend/mcl.lisp (original) +++ usocket/trunk/backend/mcl.lisp Wed Sep 15 00:19:01 2010 @@ -94,13 +94,13 @@ (reuse-address nil reuse-address-supplied-p) (backlog 5) (element-type 'character)) - (declare (ignore reuseaddress reuse-address-supplied-p)) - (let ((socket (with-mapped-conditions () - (make-instance 'passive-socket - :local-port port - :local-host host - :reuse-address reuse-address - :backlog backlog)))) + (let* ((reuseaddress (if reuse-address-supplied-p reuse-address reuseaddress)) + (socket (with-mapped-conditions () + (make-instance 'passive-socket + :local-port port + :local-host host + :reuse-address reuseaddress + :backlog backlog)))) (make-stream-server-socket socket :element-type element-type))) (defmethod socket-accept ((usocket stream-server-usocket) &key element-type) Modified: usocket/trunk/usocket-test.asd ============================================================================== --- usocket/trunk/usocket-test.asd (original) +++ usocket/trunk/usocket-test.asd Wed Sep 15 00:19:01 2010 @@ -23,7 +23,9 @@ :components ((:module "test" :components ((:file "package") (:file "test-usocket" - :depends-on ("package")))))) + :depends-on ("package")) + (:file "test-condition" + :depends-on ("test-usocket")))))) (defmethod perform ((op test-op) (c (eql (find-system :usocket-test)))) (funcall (intern "DO-TESTS" "USOCKET-TEST"))) From ctian at common-lisp.net Wed Sep 15 06:14:59 2010 From: ctian at common-lisp.net (Chun Tian (binghe)) Date: Wed, 15 Sep 2010 02:14:59 -0400 Subject: [usocket-cvs] r561 - usocket/trunk/vendor Message-ID: Author: ctian Date: Wed Sep 15 02:14:59 2010 New Revision: 561 Log: ABCL: spawn-thread now works in ABCL. Modified: usocket/trunk/vendor/spawn-thread.lisp Modified: usocket/trunk/vendor/spawn-thread.lisp ============================================================================== --- usocket/trunk/vendor/spawn-thread.lisp (original) +++ usocket/trunk/vendor/spawn-thread.lisp Wed Sep 15 02:14:59 2010 @@ -65,6 +65,9 @@ #+scl (mp:make-process #'(lambda () (apply function args)) :name name) + #+abcl + (threads:make-thread #'(lambda () (apply function args)) + :name name) #+threads-not-available (declare (ignore name function args)) #+threads-not-available From ctian at common-lisp.net Wed Sep 15 06:26:33 2010 From: ctian at common-lisp.net (Chun Tian (binghe)) Date: Wed, 15 Sep 2010 02:26:33 -0400 Subject: [usocket-cvs] r562 - in usocket/trunk: . backend Message-ID: Author: ctian Date: Wed Sep 15 02:26:32 2010 New Revision: 562 Log: ABCL: bugfix for socket-accept, now socker-server confirmed works. Modified: usocket/trunk/backend/abcl.lisp usocket/trunk/server.lisp Modified: usocket/trunk/backend/abcl.lisp ============================================================================== --- usocket/trunk/backend/abcl.lisp (original) +++ usocket/trunk/backend/abcl.lisp Wed Sep 15 02:26:32 2010 @@ -249,9 +249,9 @@ ;;; SOCKET-ACCEPT -(defmethod socket-accept ((socket stream-server-usocket) &key (element-type 'character)) - (with-mapped-conditions (socket) - (let* ((client-socket (jcall $@accept/0 socket)) +(defmethod socket-accept ((usocket stream-server-usocket) &key (element-type 'character)) + (with-mapped-conditions (usocket) + (let* ((client-socket (jcall $@accept/0 (socket usocket))) (stream (ext:get-socket-stream client-socket :element-type element-type))) (make-stream-socket :stream stream :socket client-socket)))) Modified: usocket/trunk/server.lisp ============================================================================== --- usocket/trunk/server.lisp (original) +++ usocket/trunk/server.lisp Wed Sep 15 02:26:32 2010 @@ -9,7 +9,7 @@ (timeout 1) (max-buffer-size +max-datagram-packet-size+) ;; for tcp element-type reuse-address multi-threading) - (let* ((real-host (or host #(0 0 0 0))) + (let* ((real-host (or host *wildcard-host*)) (socket (ecase protocol (:stream (apply #'socket-listen From ctian at common-lisp.net Fri Sep 24 15:16:22 2010 From: ctian at common-lisp.net (Chun Tian (binghe)) Date: Fri, 24 Sep 2010 11:16:22 -0400 Subject: [usocket-cvs] r563 - public_html Message-ID: Author: ctian Date: Fri Sep 24 11:16:20 2010 New Revision: 563 Log: Fixed HTML title (USOCKET) when editing pages using Mozilla Composer Modified: public_html/feature-comparison.shtml public_html/implementation-comparison.shtml public_html/index.shtml Modified: public_html/feature-comparison.shtml ============================================================================== --- public_html/feature-comparison.shtml (original) +++ public_html/feature-comparison.shtml Fri Sep 24 11:16:20 2010 @@ -1,19 +1,21 @@ - + - <!--#include virtual="project-name" --> + USOCKET
    -

    +

    USOCKET

    Comparison to "trivial-sockets"

    usocket supports more backends than trivial-sockets. -The latter implements different feature-sets for different backends +The +latter +implements different feature-sets for different backends while the former supplies consistent functionality for all backends.

    Modified: public_html/implementation-comparison.shtml ============================================================================== --- public_html/implementation-comparison.shtml (original) +++ public_html/implementation-comparison.shtml Fri Sep 24 11:16:20 2010 @@ -1,14 +1,14 @@ - + - <!--#include virtual="project-name" --> + USOCKET
    -

    +

    USOCKET

    Supported implementations comparison

    Different projects aim at providing TCP/IP sockets portably Modified: public_html/index.shtml ============================================================================== --- public_html/index.shtml (original) +++ public_html/index.shtml Fri Sep 24 11:16:20 2010 @@ -1,14 +1,14 @@ - + - <!--#include virtual="project-name" --> + USOCKET

    -

    +

    USOCKET

    • Goal
    • @@ -96,7 +96,9 @@ kept up to date, please subscribe to -the commit message mailing list. To use the latest development +the +commit +message mailing list. To use the latest development version, make sure you have Subversion installed and execute this command:

       $ svn checkout svn://common-lisp.net/project/usocket/svn/usocket/trunk usocket-svn
      @@ -124,6 +126,8 @@
    +interfaces +provided @@ -353,7 +358,8 @@ +API's +provided @@ -485,6 +491,8 @@ From ctian at common-lisp.net Tue Sep 28 09:15:14 2010 From: ctian at common-lisp.net (Chun Tian (binghe)) Date: Tue, 28 Sep 2010 05:15:14 -0400 Subject: [usocket-cvs] r564 - in usocket/trunk: . backend Message-ID: Author: ctian Date: Tue Sep 28 05:15:13 2010 New Revision: 564 Log: Fixed non-exist confition class: ns-try-again-condition. Thanks to Stas Boukarev Modified: usocket/trunk/backend/cmucl.lisp usocket/trunk/condition.lisp Modified: usocket/trunk/backend/cmucl.lisp ============================================================================== --- usocket/trunk/backend/cmucl.lisp (original) +++ usocket/trunk/backend/cmucl.lisp Tue Sep 28 05:15:13 2010 @@ -209,10 +209,10 @@ ;; constants mentioned in C (let ((exception (second (assoc errno - '((1 ns-host-not-found-error) ;; HOST_NOT_FOUND - (2 ns-no-recovery-error) ;; NO_DATA - (3 ns-no-recovery-error) ;; NO_RECOVERY - (4 ns-try-again)))))) ;; TRY_AGAIN + '((1 ns-host-not-found-error) ;; HOST_NOT_FOUND + (2 ns-no-recovery-error) ;; NO_DATA + (3 ns-no-recovery-error) ;; NO_RECOVERY + (4 ns-try-again-condition)))))) ;; TRY_AGAIN (when exception (error exception)))))) Modified: usocket/trunk/condition.lisp ============================================================================== --- usocket/trunk/condition.lisp (original) +++ usocket/trunk/condition.lisp Tue Sep 28 05:15:13 2010 @@ -132,7 +132,7 @@ error available.")) (define-usocket-condition-classes - (ns-try-again) + (ns-try-again-condition) (ns-condition)) (define-condition ns-unknown-condition (ns-condition) From ctian at common-lisp.net Tue Sep 28 09:16:01 2010 From: ctian at common-lisp.net (Chun Tian (binghe)) Date: Tue, 28 Sep 2010 05:16:01 -0400 Subject: [usocket-cvs] r565 - in usocket/branches/0.4.x: . backend Message-ID: Author: ctian Date: Tue Sep 28 05:16:01 2010 New Revision: 565 Log: Fixed non-exist confition class: ns-try-again-condition. Thanks to Stas Boukarev Modified: usocket/branches/0.4.x/backend/cmucl.lisp usocket/branches/0.4.x/condition.lisp Modified: usocket/branches/0.4.x/backend/cmucl.lisp ============================================================================== --- usocket/branches/0.4.x/backend/cmucl.lisp (original) +++ usocket/branches/0.4.x/backend/cmucl.lisp Tue Sep 28 05:16:01 2010 @@ -163,10 +163,10 @@ ;; constants mentioned in C (let ((exception (second (assoc errno - '((1 ns-host-not-found-error) ;; HOST_NOT_FOUND - (2 ns-no-recovery-error) ;; NO_DATA - (3 ns-no-recovery-error) ;; NO_RECOVERY - (4 ns-try-again)))))) ;; TRY_AGAIN + '((1 ns-host-not-found-error) ;; HOST_NOT_FOUND + (2 ns-no-recovery-error) ;; NO_DATA + (3 ns-no-recovery-error) ;; NO_RECOVERY + (4 ns-try-again-condition)))))) ;; TRY_AGAIN (when exception (error exception)))))) Modified: usocket/branches/0.4.x/condition.lisp ============================================================================== --- usocket/branches/0.4.x/condition.lisp (original) +++ usocket/branches/0.4.x/condition.lisp Tue Sep 28 05:16:01 2010 @@ -131,7 +131,7 @@ error available.")) (define-usocket-condition-classes - (ns-try-again) + (ns-try-again-condition) (ns-condition)) (define-condition ns-unknown-condition (ns-condition) From ctian at common-lisp.net Tue Sep 28 09:17:06 2010 From: ctian at common-lisp.net (Chun Tian (binghe)) Date: Tue, 28 Sep 2010 05:17:06 -0400 Subject: [usocket-cvs] r566 - in usocket/branches/0.3.x: . backend Message-ID: Author: ctian Date: Tue Sep 28 05:17:06 2010 New Revision: 566 Log: Fixed non-exist confition class: ns-try-again-condition. Thanks to Stas Boukarev Modified: usocket/branches/0.3.x/backend/cmucl.lisp usocket/branches/0.3.x/condition.lisp Modified: usocket/branches/0.3.x/backend/cmucl.lisp ============================================================================== --- usocket/branches/0.3.x/backend/cmucl.lisp (original) +++ usocket/branches/0.3.x/backend/cmucl.lisp Tue Sep 28 05:17:06 2010 @@ -144,10 +144,10 @@ ;; constants mentioned in C (let ((exception (second (assoc errno - '((1 ns-host-not-found-error) ;; HOST_NOT_FOUND - (2 ns-no-recovery-error) ;; NO_DATA - (3 ns-no-recovery-error) ;; NO_RECOVERY - (4 ns-try-again)))))) ;; TRY_AGAIN + '((1 ns-host-not-found-error) ;; HOST_NOT_FOUND + (2 ns-no-recovery-error) ;; NO_DATA + (3 ns-no-recovery-error) ;; NO_RECOVERY + (4 ns-try-again-condition)))))) ;; TRY_AGAIN (when exception (error exception)))))) Modified: usocket/branches/0.3.x/condition.lisp ============================================================================== --- usocket/branches/0.3.x/condition.lisp (original) +++ usocket/branches/0.3.x/condition.lisp Tue Sep 28 05:17:06 2010 @@ -90,7 +90,7 @@ (define-usocket-condition-classes - (ns-try-again) + (ns-try-again-condition) (ns-condition)) (define-condition ns-unknown-condition (ns-condition) From ctian at common-lisp.net Thu Sep 30 08:45:36 2010 From: ctian at common-lisp.net (Chun Tian (binghe)) Date: Thu, 30 Sep 2010 04:45:36 -0400 Subject: [usocket-cvs] r567 - usocket/trunk Message-ID: Author: ctian Date: Thu Sep 30 04:45:35 2010 New Revision: 567 Log: Export +max-datagram-packet-size+ Modified: usocket/trunk/package.lisp Modified: usocket/trunk/package.lisp ============================================================================== --- usocket/trunk/package.lisp (original) +++ usocket/trunk/package.lisp Thu Sep 30 04:45:35 2010 @@ -13,6 +13,8 @@ #:*remote-host* ; special variables (udp) #:*remote-port* + #:+max-datagram-packet-size+ + #:socket-connect ; socket constructors and methods #:socket-listen #:socket-accept From ctian at common-lisp.net Wed Sep 15 04:06:06 2010 From: ctian at common-lisp.net (Chun Tian (binghe)) Date: Wed, 15 Sep 2010 04:06:06 -0000 Subject: [usocket-cvs] r559 - public_html Message-ID: Author: ctian Date: Wed Sep 15 00:06:05 2010 New Revision: 559 Log: Update other Web pages with new progress. Modified: public_html/feature-comparison.shtml public_html/implementation-comparison.shtml public_html/index.shtml Modified: public_html/feature-comparison.shtml ============================================================================== --- public_html/feature-comparison.shtml (original) +++ public_html/feature-comparison.shtml Wed Sep 15 00:06:05 2010 @@ -1,154 +1,163 @@ - - - + + - <!--#include virtual="project-name" --> - - + <!--#include virtual="project-name" --> + + - -
    -

    -
    - -

    Comparison to "trivial-sockets"

    - +
    +

    +
    +

    Comparison to "trivial-sockets"

    usocket supports more backends than trivial-sockets. - The latter implements different feature-sets for different backends while - the former supplies consistent functionality for all backends.

    - -
    -
    Allegro + +
    Investigate -interfaces provided DONE DONE DONEImplement udp socket support. Investigate -API's provided DONE DONE DONEAdd support for Scieneer Common Lisp, fix + + issue #6 and API preparation for server side sockets (not in this release)
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +The latter implements different feature-sets for different backends +while the former supplies consistent functionality for all backends.

    +
    +
    FeatureIn trivial-sockets?In usocket?
    ABCLACLclispCMUCLLispWorksOpenMCLSBCLoverall
    Client side tcp streams:element-typeYes Yes*YesYesYesYes*YesYesYes
    :external-formatNoNoYesNoNoNoNoNoNo
    binding local interface/portNoYesNoNoNoYesYesNoNo
    Server socket creationBinding specific local portYes
    Binding specific local interfaceNoYesNoYesNoYesYesNoYes
    Selectable backlog lengthNoYesNoYesNoYesYesNoYes
    reuse-addressYesYesNo*YesYesYesYesNo*Yes*
    :element-type for created connectionsNoYes
    Accepting connections:element-type for created streamYesYes*YesYesYesYes*YesYesYes*
    :external-format for created streamNoNoYesNoNoNoNoNoNo
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FeatureIn trivial-sockets?In usocket?

    +
    ABCLACLclispCMUCLLispWorksOpenMCLSBCLoverall
    Client side tcp streams:element-typeYes Yes*YesYesYesYes*YesYesYes
    :external-formatNoNoYesNoNoNoNoNoNo
    binding local interface/portNoYesNoNoNoYesYesNoYes
    Server socket creationBinding specific local portYes
    Binding specific local interfaceNoYesNoYesNoYesYesNoYes
    Selectable backlog lengthNoYesNoYesNoYesYesNoYes
    reuse-addressYesYesNo*YesYesYesYesNo*Yes*
    :element-type for created connectionsNoYes
    Accepting connections:element-type for created streamYesYes*YesYesYesYes*YesYesYes*
    :external-format for created streamNoNoYesNoNoNoNoNoNo
    - -

    In summary: there are only a very limited number of features you can depend +

    In summary: there are only a very limited number of features you can +depend on to work on all platforms supported by trivial-sockets. While usocket -doesn't support all features, you can depend on the features to be available. +doesn't support all features, you can depend on the features to be +available.

    - -
    - -
    -Back to Common-lisp.net. +
    +
    Back +to Common-lisp.net. +
    + - Modified: public_html/implementation-comparison.shtml ============================================================================== --- public_html/implementation-comparison.shtml (original) +++ public_html/implementation-comparison.shtml Wed Sep 15 00:06:05 2010 @@ -1,68 +1,155 @@ - - - + + - <!--#include virtual="project-name" --> - - + <!--#include virtual="project-name" --> + + - -
    -

    -
    - +
    +

    +

    Supported implementations comparison

    -

    Different projects aim at providing TCP/IP sockets portably -across Common Lisp implementations. The table below summarizes +across Common Lisp implementations. The table below summarizes the state of several of these libraries.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Supported implementations comparison
    Implementationtrivial-socketsACL-COMPATs-sysdepsusocketkmrclIOLib
    SBCLyesyesyesyesyesyes
    CMUCLyesyesyesyesyesyes
    ArmedBearyesnonoyesnono
    clispyesyesnoyesyesyes
    Allegroyesnot relevantnoyesyesno
    LispWorksyesyesyesyesyesno
    OpenMCLyesyesyesyesyesno
    ECLnononoyesnono
    Scieneernoyesnoyesnono
    GCLnononono (to come)nono
    Cormannoyesnono (to come)nono
    Total #87(+1)4963
    Supported implementations comparison
    Implementationtrivial-socketsACL-COMPATs-sysdepsusocketkmrclIOLib
    SBCLyesyesyesyesyesyes
    CMUCLyesyesyesyesyesyes
    ArmedBearyesnonoyesnono
    clispyesyesnoyesyesyes
    Allegroyesnot relevantnoyesyesno
    LispWorksyesyesyesyesyesno
    OpenMCLyesyesyesyesyesno
    ECLnononoyesnono
    Scieneernoyesnoyesnono
    GCLnononono (to come)nono
    Cormannoyesnono (to come)nono
    Digitool MCLnononoyesnono
    Total #87(+1)41063
    - - -
    - -
    -Back to Common-lisp.net. +
    +
    Back +to Common-lisp.net. +
    + - Modified: public_html/index.shtml ============================================================================== --- public_html/index.shtml (original) +++ public_html/index.shtml Wed Sep 15 00:06:05 2010 @@ -1,171 +1,160 @@ - - + - <!--#include virtual="project-name" --> - - + <!--#include virtual="project-name" --> + + - -
    -

    -
    - +
    +

    +
    -

    Goal

    - -

    The project wants to provide a portable TCP/IP (and later on maybe -UDP) socket interface for as many Common Lisp implementations as +

    The project wants to provide a portable TCP/IP and UDP/IP socket +interface for as many Common Lisp implementations as possible, while keeping the abstraction and portability layer as thin as possible.

    -

    Because trivial-sockets has been declared dead and its author has said he will declare usocket -its successor if there is a zero effort path of migration, I'm also working -on trivial-usocket which is supposed to be a sub-optimal, but zero +its successor if there is a zero effort path of migration, I'm also +working +on trivial-usocket which is supposed to be a sub-optimal, +but zero effort migration from trivial-sockets.

    -

    If your lisp isn't mentioned in the list below, please feel free to submit a request for it at the mailing list mentioned below.

    -

    Comparison to other socket libraries

    - -

    Since usocket is effectively the succesor to trivial-sockets, see the - feature comparison with - trivial-sockets in order to find out which one you should use.

    - +

    Since usocket is effectively the succesor to trivial-sockets, see +the feature comparison with +trivial-sockets in order to find out which one you should use.

    After starting the project, many others turned out to have worked on - something alike, many times as part of a broader project or library. - Some of them were known at the start of this project, others have - been conceived after the usocket project already started. Not all of - them have exactly the same portability goal.

    - +something alike, many times as part of a broader project or library. +Some of them were known at the start of this project, others have been +conceived after the usocket project already started. Not all of them +have exactly the same portability goal.

    See the Implementation - comparison page for a comparison of the portability of other - libaries and how that relates to usocket.

    - - +comparison page for a comparison of the portability of other +libaries and how that relates to usocket.

    Documentation

    - -

    See the documentation page for the API description.

    - +

    See the documentation page for the API +description.

    Supported implementations

    -

    Currently these implementations are supported:

    -
    • SBCL
    • CMUCL
    • -
    • Armedbear (0.0.10 and up)
    • -
    • clisp
    • -
    • Allegro
    • +
    • ABCL (Armedbear)
      +
    • +
    • GNU CLISP
      +
    • +
    • Allegro CL
      +
    • LispWorks (5.0 and up)
    • -
    • OpenMCL
    • +
    • Clozure CL (aka OpenMCL)
    • ECL
    • -
    • Scieneer
    • +
    • Scieneer CL
      +
    • +
    • Digitool MCL (5.0 and up)
      +
    -

    Community

    - -

    This project has started Januari 2006. There isn't much of a community - yet, though I'd like there to be one. So, you're invited to join - the mailing list, announce yourself and even join the effort! -

    - - -

    Development discussion takes place on - usocket-devel at common-lisp.net. -

    - -

    Project tracking happens in the - project's Trac setup. Please take note of the guidelines before - entering a bug or enhancement request into the database.

    - - +

    This project has started Januari 2006. There isn't much of a +community yet, though I'd like there to be one. So, you're invited to +join the mailing list, announce yourself and even join the effort!

    +

    Development discussion takes place on usocket-devel at common-lisp.net. +

    +

    Project tracking happens in the project's Trac setup. +Please take note of the guidelines before entering a bug or enhancement +request into the database.

    -

    Development

    - -

    Development will at least follow the steps outlined below. - Yet to be determined is whether the currently mentioned steps will - be enough to release version 1.0. Possibly, UDP sockets remain to be - addressed before doing 1.0; that will depend on your reactions :-) -

    -

    The targeted implementations listed in the status table below are not - a final list: others can be added if/when the need or interest arrises. -

    -

    Active development is taking place in the - Subversion repository. - To be kept up to date, please - subscribe to the commit message mailing list. To use the latest - development version, make sure you have Subversion installed and - execute this command: -

    - -
    - $ svn checkout svn://common-lisp.net/project/usocket/svn/usocket/trunk usocket-svn
    -  
    - -

    Please send patches, bug reports and suggestions to the development - mailing list address given above. The table below indicates the - current state of development. -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +

    Development

    +

    Development will at least follow the steps outlined below. Yet to be +determined is whether the currently mentioned steps will be enough to +release version 1.0. Possibly, UDP sockets remain to be addressed +before doing 1.0; that will depend on your reactions :-)

    +

    The targeted implementations listed in the status table below are +not a final list: others can be added if/when the need or interest +arrises.

    +

    Active +development is taking place in the Subversion repository. To be +kept up to date, please subscribe +to +the commit message mailing list. To use the latest development +version, make sure you have Subversion +installed and execute this command:

    +
     $ svn checkout svn://common-lisp.net/project/usocket/svn/usocket/trunk usocket-svn
    +

    Please send patches, bug reports and suggestions to the development +mailing list address given above. The table below indicates the current +state of development.

    +
    Status for the currently targeted backends
    Major stepsSocket implementations
    Minor stepsSBCLCMUCLABCLclispAllegroLispWorksOpenMCLECLScieneer
    Minimal active sockets support - at the same level as provided by - trivial-sockets.
    - (Meaning streamed tcp traffic on connected sockets.)
    Investigate interfaces provided.DONE DONE DONE DONE DONE DONE DONE DONE DONE
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -177,6 +166,7 @@ + @@ -189,6 +179,7 @@ + @@ -201,6 +192,7 @@ + @@ -213,22 +205,26 @@ + - - - - - - - - - - - - + + + + + + + + + + + + + @@ -240,6 +236,7 @@ + @@ -252,20 +249,22 @@ + - + - - - - - - - - - + + + + + + + + + + @@ -278,6 +277,7 @@ + @@ -290,19 +290,21 @@ + - - +in one function call (select() like behaviour). + + + - @@ -314,16 +316,16 @@ - + + - + - + @@ -345,134 +347,174 @@ + - - - - - - - - - + + + + + + + + + + - - - - - - - - + + + + + + + + +
    Status for the +currently targeted backends
    Major stepsSocket implementations

    +
    Minor stepsSBCLCMUCLABCLCLISPAllegro + +
    +
    LispWorksCCLECLScieneerMCL
    Minimal active sockets support at the same level +as provided by trivial-sockets.
    +(Meaning streamed tcp traffic on connected sockets.)
    Investigate +interfaces +provided.DONE DONE DONE DONE DONE DONE DONE DONE DONEDONE
    +
    Identify socket errors generated. DONEDONE DONE DONEDONE
    Implement active socket support.DONE DONE DONEDONE
    Implement remapping of implementation defined errors.DONE DONE DONEDONE
    Implementation test-suite statusPASS PASS PASSPASS
    Add functions to retrieve socket properties:
    - Local and remote IP address and port.
    Investigate interfaces providedDONE DONE DONE DONE DONE DONE DONE DONE DONE
    Add functions to retrieve socket properties:
    +Local and remote IP address and port.
    Investigate +interfaces +providedDONE DONE DONE DONE DONE DONE DONE DONE DONEDONE
    Implement it. DONEDONE DONE DONEDONE
    Implementation test-suite statusPASS PASS PASSPASS
    Add support for passive (connection-accepting/server) - sockets.Add support for passive +(connection-accepting/server) sockets. Investigate interfaces providedWIPWIPWIPWIPWIPWIPWIPWIPWIPDONEDONEDONEDONEDONEDONEDONEDONEDONEDONE
    Implement api calls listen and acceptDONE DONE DONEDONE
    Implement api calls get- and setsockopt (or equivalent).WIP WIP WIPWIP
    Implement efficient waiting for multiple sockets - in one function call (select() like behaviour). - Investigate interfaces providedInvestigate +interfaces providedDONEDONE DONE DONE DONE DONE DONEdone DONE DONE DONEDONE DONE DONEdoneDONEDONE DONE DONE DONE
    Implement more uncommon api calls - for tcp streams.Implement more uncommon api calls for tcp streams. send, recvTODO TODO TODO TODOTODO TODO TODOTODO
    Implement udp socket support. - Investigate API's providedWIPWIPWIPWIPWIPWIPWIPWIPInvestigate +API's providedDONEDONEDONEDONEDONEDONEDONEDONEDONE WIP
    Build on top of that (or custom ffi).WIPWIPWIPWIPWIPWIPWIPWIPDONEDONEDONEDONEDONEDONEDONEDONEDONE WIP
    -

    Interface guarantees

    -

    The interfaces currently published in the :export part of the package definition are guaranteed to stay compatible for the -entire 0.x lifecycle. Extention in a backward compatible way is +entire 0.x lifecycle. Extention in a backward compatible way is ofcourse valid, as is the addition of new interface functions.

    -

    Releases

    -

    Current release

    Releases are uploaded to the releases/ - directory. You can find short descriptions in the table below:

    - +directory. You can find short descriptions in the table below:

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Release history
    DateReleaseSummary
    Dec 27, 20080.4.1fixes for ECL, LispWorks, SBCL, SCL
    Oct 28, 20080.4.0select()-like api: make a single thread wait for multiple sockets.
    - various socket options for socket-creation with SOCKET-CONNECT. -
    Jun 21, 20080.3.6Code fixups based on advice from the ECL and OpenMCL maintainers. - New exported symbols: WITH-MAPPED-CONDITIONS, NS-CONDITION, - NS-ERROR, NS-UNKNOWN-ERROR and NS-UNKNOWN-CONDITION.
    Jul 25, 20070.3.4Fix clisp get-host-name, multiple ECL fixes.
    Jun 05, 20070.3.3Fix where host resolution routine was unable to resolve would return - NIL instead of erroring.
    Mar 04, 20070.3.2Fixes for many backends related to closing sockets. - LispWorks fix for broken server sockets. - API guarantee adjustments in preparation of porting Drakma.
    Feb 28, 20070.3.1fixed with-server-socket; prevent creation of invalid sockets; - 2 more convenience macros.
    Feb 26, 2007re-releaseRe-release of 0.2.3, 0.2.4, 0.2.5 and 0.3.0 tarballs - because the originals included Subversion administration areas.
    Jan 21, 20070.3.0Server sockets
    Jan 19, 20070.2.5Allegro compilation fix.
    Jan 17, 20070.2.4Various fixes for CMUCL, OpenMCL, Allegro and LispWorks. -
    Jan 04, 20070.2.3Add :element-type support to support stacking - flexi-streams on socket streams for portable :external-format - support.
    Jan 03, 20070.2.2Add ECL support and a small SBCL bugfix.
    Dec 21, 20060.2.1Remove 'open-stream' interface which is supposed - to be provided by the 'trivial-usocket' package.
    Dec 18, 20060.2.0Add support for - Scieneer - Common Lisp, fix issue #6 and - API preparation for server side sockets (not in this release)
    Feb 13, 20060.1.0Initial release
    Release history
    DateReleaseSummary
    Dec 27, 20080.4.1fixes for ECL, LispWorks, SBCL, SCL
    Oct 28, 20080.4.0select()-like api: make a single thread wait for +multiple sockets.
    + various socket options for socket-creation with +SOCKET-CONNECT.
    Jun 21, 20080.3.6Code fixups based on advice from the ECL and OpenMCL +maintainers. New exported symbols: WITH-MAPPED-CONDITIONS, +NS-CONDITION, NS-ERROR, NS-UNKNOWN-ERROR and NS-UNKNOWN-CONDITION.
    Jul 25, 20070.3.4Fix clisp get-host-name, multiple ECL fixes.
    Jun 05, 20070.3.3Fix where host resolution routine was unable to resolve would +return NIL instead of erroring.
    Mar 04, 20070.3.2Fixes for many backends related to closing sockets. LispWorks +fix for broken server sockets. API guarantee adjustments in preparation +of porting Drakma.
    Feb 28, 20070.3.1fixed with-server-socket; prevent creation of invalid +sockets; 2 more convenience macros.
    Feb 26, 2007re-releaseRe-release of 0.2.3, 0.2.4, 0.2.5 and 0.3.0 tarballs because +the originals included Subversion administration areas.
    Jan 21, 20070.3.0Server sockets
    Jan 19, 20070.2.5Allegro compilation fix.
    Jan 17, 20070.2.4Various fixes for CMUCL, OpenMCL, Allegro and LispWorks.
    Jan 04, 20070.2.3Add :element-type support to support stacking flexi-streams +on socket streams for portable :external-format support.
    Jan 03, 20070.2.2Add ECL support and a small SBCL bugfix.
    Dec 21, 20060.2.1Remove 'open-stream' interface which is supposed to be +provided by the 'trivial-usocket' package.
    Dec 18, 20060.2.0Add support for Scieneer Common Lisp, +fix + issue #6 +and API preparation for server side sockets (not in this release)
    Feb 13, 20060.1.0Initial release
    - - - -

    Project history

    -

    Long ago the project was conceived and started by Erik Enge in an attempt to factor out all implementation specific sockets code from cl-irc. This 'long ago' must have been way before 2003 when I entered the cl-irc project.

    -

    In january 2006, Erik Huelsmann found Erik Enge willing to donate -the code he had still laying around to restart the project. The restart -took place at the 27th of january when the old code was imported into the -public repository.

    - -
    - -
    -Back to Common-lisp.net. +the code he had still laying around to restart the project. The restart +took place at the 27th of january when the old code was imported into +the +public repository.
    +

    +

    Starting from 2008, Chun Tian (binghe) joined into usocket +development team with his UDP code base.
    +

    +
    +
    Back +to Common-lisp.net. +
    + -