diff -Nru jruby-0.8.2/src/org/jruby/RubyBasicSocket.java jruby-0.8.2-send-recv/src/org/jruby/RubyBasicSocket.java
--- jruby-0.8.2/src/org/jruby/RubyBasicSocket.java	2005-04-02 08:04:39.000000000 -0800
+++ jruby-0.8.2-send-recv/src/org/jruby/RubyBasicSocket.java	2006-03-23 11:48:01.000000000 -0800
@@ -29,10 +29,13 @@
 
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.EOFException;
+import java.io.IOException;
 
 import org.jruby.javasupport.JavaObject;
 import org.jruby.runtime.builtin.IRubyObject;
-
+import org.jruby.util.IOHandlerSocket;
+import org.jruby.util.IOHandler;
 
 public class RubyBasicSocket extends RubyIO {
 
@@ -46,7 +49,13 @@
         
         InputStream inputStream = (InputStream) extractStream(input);
         OutputStream outputStream = (OutputStream) extractStream(output);
-        bindStreams(inputStream, outputStream);
+        try {
+            handler = new IOHandlerSocket(getRuntime(), inputStream, outputStream);
+    	} catch (IOException e) {
+            throw getRuntime().newIOError(e.getMessage());
+        }
+        registerIOHandler(handler);
+        modes = handler.getModes();
         
         return this;
     }
@@ -55,4 +64,27 @@
         IRubyObject javaObject = proxyObject.getInstanceVariable("@java_object");
         return ((JavaObject)javaObject).getValue();
     }
+
+    public IRubyObject send(IRubyObject[] args) {
+	return syswrite(args[0]);
+    }
+    
+    public IRubyObject recv(IRubyObject[] args) {
+	try {
+            return getRuntime().newString(((IOHandlerSocket) handler).recv(RubyNumeric.fix2int(args[0])));
+        } catch (IOHandler.BadDescriptorException e) {
+            throw getRuntime().newErrnoEBADFError();
+        } catch (EOFException e) {
+	    // recv returns nil on EOF
+	    return getRuntime().getNil();
+    	} catch (IOException e) {
+	    // All errors to sysread should be SystemCallErrors, but on a closed stream
+	    // Ruby returns an IOError.  Java throws same exception for all errors so
+	    // we resort to this hack...
+	    if ("Socket not open".equals(e.getMessage())) {
+		throw getRuntime().newIOError(e.getMessage());
+	    }
+    	    throw getRuntime().newSystemCallError(e.getMessage());
+    	}
+    }
 }
diff -Nru jruby-0.8.2/src/org/jruby/runtime/builtin/meta/BasicSocketMetaClass.java jruby-0.8.2-send-recv/src/org/jruby/runtime/builtin/meta/BasicSocketMetaClass.java
--- jruby-0.8.2/src/org/jruby/runtime/builtin/meta/BasicSocketMetaClass.java	2005-08-28 06:29:32.000000000 -0700
+++ jruby-0.8.2-send-recv/src/org/jruby/runtime/builtin/meta/BasicSocketMetaClass.java	2006-03-23 12:00:39.000000000 -0800
@@ -32,6 +32,7 @@
 import org.jruby.RubyClass;
 import org.jruby.RubyModule;
 import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.runtime.Arity;
 
 public class BasicSocketMetaClass extends ObjectMetaClass {
 
@@ -45,6 +46,8 @@
     }
     
     protected void initializeClass() {
+	defineMethod("send", Arity.optional(), "send");
+        defineMethod("recv", Arity.optional(), "recv");
     }
 
     public RubyClass newSubClass(String name, RubyModule parentModule) {
diff -Nru jruby-0.8.2/src/org/jruby/util/IOHandler.java jruby-0.8.2-send-recv/src/org/jruby/util/IOHandler.java
--- jruby-0.8.2/src/org/jruby/util/IOHandler.java	2005-09-06 07:57:57.000000000 -0700
+++ jruby-0.8.2-send-recv/src/org/jruby/util/IOHandler.java	2006-03-23 11:33:04.000000000 -0800
@@ -258,7 +258,7 @@
         return syswrite(string);
     }
     
-    private int sysread(StringBuffer buf, int length) throws IOException {
+    protected int sysread(StringBuffer buf, int length) throws IOException {
         if (buf == null) {
             throw new IOException("sysread2: Buf is null");
         }
diff -Nru jruby-0.8.2/src/org/jruby/util/IOHandlerSocket.java jruby-0.8.2-send-recv/src/org/jruby/util/IOHandlerSocket.java
--- jruby-0.8.2/src/org/jruby/util/IOHandlerSocket.java	1969-12-31 16:00:00.000000000 -0800
+++ jruby-0.8.2-send-recv/src/org/jruby/util/IOHandlerSocket.java	2006-03-23 11:50:30.000000000 -0800
@@ -0,0 +1,78 @@
+/***** BEGIN LICENSE BLOCK *****
+ * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Common Public
+ * License Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Copyright (C) 2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
+ * Copyright (C) 2004 Thomas E Enebo <enebo@acm.org>
+ * Copyright (C) 2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
+ * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
+ * Copyright (C) 2005 David Corbin <dcorbin@users.sourceforge.net>
+ * Copyright (C) 2005 Charles O Nutter <headius@headius.com>
+ * 
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the CPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the CPL, the GPL or the LGPL.
+ ***** END LICENSE BLOCK *****/
+package org.jruby.util;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.jruby.Ruby;
+import org.jruby.util.IOHandlerUnseekable;
+
+/**
+ * @author evan
+ *
+ */
+public class IOHandlerSocket extends IOHandlerUnseekable {
+
+    /**
+     * @param inStream
+     * @param outStream
+     * @throws IOException 
+     */
+    public IOHandlerSocket(Ruby runtime, InputStream inStream, 
+                     OutputStream outStream) throws IOException {
+	super(runtime, inStream, outStream);
+    }
+
+    public String recv(int len) throws IOException, BadDescriptorException {
+	if(!isOpen()) {
+	    throw new IOException("Socket not open");
+	}
+	if(len < 1) {
+	    return "";
+	}
+	// this should provide blocking until data is available...
+	int c = sysread();
+	if(c == -1) {
+	    throw new EOFException();
+	}
+	int available = getInputStream().available();
+	len = len - 1 < available ? len - 1 : available;
+	StringBuffer buf = new StringBuffer();
+	buf.append((char) c);
+	sysread(buf, len);
+	return buf.toString();
+    }
+}
