[usocket-cvs] r503 - usocket/branches/experimental-udp/backend

Chun Tian (binghe) ctian at common-lisp.net
Sat Dec 12 21:57:41 UTC 2009


Author: ctian
Date: Sat Dec 12 16:57:40 2009
New Revision: 503

Log:
Buggy UDP support for ABCL (only socket-connect works now)

Modified:
   usocket/branches/experimental-udp/backend/armedbear.lisp

Modified: usocket/branches/experimental-udp/backend/armedbear.lisp
==============================================================================
--- usocket/branches/experimental-udp/backend/armedbear.lisp	(original)
+++ usocket/branches/experimental-udp/backend/armedbear.lisp	Sat Dec 12 16:57:40 2009
@@ -6,7 +6,7 @@
 (in-package :usocket)
 
 
-;;;;; Proposed contribution to the JAVA package
+;;; Proposed contribution to the JAVA package
 
 (defpackage :jdi
   (:use :cl)
@@ -186,24 +186,36 @@
   (typecase condition
     (error (error 'unknown-error :socket socket :real-error condition))))
 
-(defun socket-connect (host port &key (element-type 'character)
+(defun socket-connect (host port &key (protocol :stream) (element-type 'character)
                        timeout deadline (nodelay nil nodelay-specified)
                        local-host local-port)
   (when deadline (unsupported 'deadline 'socket-connect))
-  (when local-host (unimplemented 'local-host 'socket-connect))
-  (when local-port (unimplemented 'local-port 'socket-connect))
 
   (let ((usock))
     (with-mapped-conditions (usock)
-      (let* ((sock-addr (jdi:jcoerce
-                         (jdi:do-jnew-call "java.net.InetSocketAddress"
-                           (host-to-hostname host)
-                           (jdi:jcoerce port :int))
-                         "java.net.SocketAddress"))
-             (jchan (jdi:do-jstatic-call "java.nio.channels.SocketChannel"
-                      "open" sock-addr))
+      (let* ((sock-addr (when (and host port)
+			  (jdi:jcoerce
+			   (jdi:do-jnew-call "java.net.InetSocketAddress"
+			     (host-to-hostname host)
+			     (jdi:jcoerce port :int))
+			   "java.net.SocketAddress")))
+	     (local-addr (when (or local-host local-port)
+			   (jdi:jcoerce
+			    (jdi:do-jnew-call "java.net.InetSocketAddress"
+			      (host-to-hostname (or host *wildcard-host*))
+			      (jdi:jcoerce (or port *auto-port*) :int))
+			    "java.net.SocketAddress")))
+             (jchan (jdi:do-jstatic-call (ecase protocol
+					   (:stream "java.nio.channels.SocketChannel")
+					   (:datagram "java.nio.channels.DatagramChannel"))
+		      "open"))
              (sock (jdi:do-jmethod-call jchan "socket")))
-        (when nodelay-specified
+	;; TODO: Fix it
+	(when (or local-host local-port)
+	  (jdi:do-jmethod-call sock "bind" local-addr))
+	(when (and host port)
+	  (jdi:do-jmethod-call jchan "connect" sock-addr))
+        (when (and (eq protocol 'stream) nodelay-specified)
           (jdi:do-jmethod-call sock "setTcpNoDelay"
                                (if nodelay
                                    (java:make-immediate-object t :boolean)
@@ -212,10 +224,14 @@
           (jdi:do-jmethod-call sock "setSoTimeout"
                                     (truncate (* 1000 timeout))))
         (setf usock
-              (make-stream-socket
-               :socket jchan
-               :stream (ext:get-socket-stream (jdi:jop-deref sock)
-                                              :element-type element-type)))))))
+	      (ecase protocol
+		(:stream
+		 (make-stream-socket
+		  :socket jchan
+		  :stream (ext:get-socket-stream (jdi:jop-deref sock)
+						 :element-type element-type)))
+		(:datagram
+		 (make-datagram-socket jchan))))))))
 
 (defun socket-listen (host port
                            &key reuseaddress
@@ -447,4 +463,29 @@
         w))
 
 (defun %remove-waiter (wl w)
-  (remhash (socket w) (wait-list-%wait wl)))
\ No newline at end of file
+  (remhash (socket w) (wait-list-%wait wl)))
+
+;;
+;; UDP support
+;;
+
+(defmethod socket-send ((socket datagram-usocket) buffer length &key host port)
+  (let ((jchan (socket socket)))
+    (let ((srcs (jdi:jcoerce buffer "java.nio.ByteBuffer"))
+	  (offset (jdi:jcoerce 0 :int))
+	  (length (jdi:jcoerce length :int)))
+      (if (and host port)
+	  (let ((target (jdi:jcoerce
+			 (jdi:do-jnew-call "java.net.InetSocketAddress"
+			   (host-to-hostname host)
+			   (jdi:jcoerce port :int))
+			 "java.net.SocketAddress")))
+	    ;; how to use "length" argument here? --binghe, 2009/12/12
+	    (jdi:do-jmethod-call jchan "send" buffer target))
+	  (jdi:do-jmethod-call jchan "write" srcs offset length)))))
+
+(defmethod socket-receive ((socket datagram-usocket) buffer length)
+  (let ((jchan (socket socket)))
+    (multiple-value-bind (buffer size host port)
+	0
+      (values buffer size host port))))




More information about the usocket-cvs mailing list