1 28 package org.jruby.ext.socket; 29 30 import java.io.IOException ; 31 32 import java.net.ConnectException ; 33 import java.net.InetAddress ; 34 import java.net.InetSocketAddress ; 35 import java.net.UnknownHostException ; 36 37 import java.nio.channels.SocketChannel ; 38 39 import org.jruby.Ruby; 40 import org.jruby.RubyClass; 41 import org.jruby.RubyNumeric; 42 import org.jruby.runtime.CallbackFactory; 43 import org.jruby.runtime.Block; 44 import org.jruby.runtime.ObjectAllocator; 45 import org.jruby.runtime.builtin.IRubyObject; 46 47 50 public class RubyTCPSocket extends RubyIPSocket { 51 static void createTCPSocket(Ruby runtime) { 52 RubyClass rb_cTCPSocket = runtime.defineClass("TCPSocket", runtime.getClass("IPSocket"), TCPSOCKET_ALLOCATOR); 53 CallbackFactory cfact = runtime.callbackFactory(RubyTCPSocket.class); 54 55 rb_cTCPSocket.includeModule(runtime.getClass("Socket").getConstant("Constants")); 56 57 rb_cTCPSocket.defineFastMethod("initialize", cfact.getFastMethod("initialize",IRubyObject.class, IRubyObject.class)); 58 rb_cTCPSocket.defineFastMethod("setsockopt", cfact.getFastOptMethod("setsockopt")); 59 rb_cTCPSocket.getMetaClass().defineFastMethod("gethostbyname", cfact.getFastSingletonMethod("gethostbyname", IRubyObject.class)); 60 rb_cTCPSocket.getMetaClass().defineMethod("open", cfact.getOptSingletonMethod("open")); 61 62 runtime.getObject().setConstant("TCPsocket",rb_cTCPSocket); 63 } 64 65 private static ObjectAllocator TCPSOCKET_ALLOCATOR = new ObjectAllocator() { 66 public IRubyObject allocate(Ruby runtime, RubyClass klass) { 67 return new RubyTCPSocket(runtime, klass); 68 } 69 }; 70 71 public RubyTCPSocket(Ruby runtime, RubyClass type) { 72 super(runtime, type); 73 } 74 75 public IRubyObject initialize(IRubyObject arg1, IRubyObject port) { 76 try { 77 InetSocketAddress addr = new InetSocketAddress (InetAddress.getByName(arg1.convertToString().toString()),RubyNumeric.fix2int(port)); 78 SocketChannel channel = SocketChannel.open(addr); 79 channel.finishConnect(); 80 setChannel(channel); 81 } catch(ConnectException e) { 82 throw getRuntime().newErrnoECONNREFUSEDError(); 83 } catch(UnknownHostException e) { 84 throw sockerr(this, "initialize: name or service not known"); 85 } catch(IOException e) { 86 throw sockerr(this, "initialize: name or service not known"); 87 } 88 return this; 89 } 90 91 public IRubyObject setsockopt(IRubyObject[] args) { 92 return getRuntime().getNil(); 94 } 95 96 public static IRubyObject open(IRubyObject recv, IRubyObject[] args, Block block) { 97 RubyTCPSocket sock = (RubyTCPSocket)recv.callMethod(recv.getRuntime().getCurrentContext(),"new",args); 98 if (!block.isGiven()) return sock; 99 100 try { 101 return recv.getRuntime().getCurrentContext().yield(sock, block); 102 } finally { 103 if (sock.isOpen()) sock.close(); 104 } 105 } 106 107 public static IRubyObject gethostbyname(IRubyObject recv, IRubyObject hostname) { 108 try { 109 IRubyObject[] ret = new IRubyObject[4]; 110 Ruby r = recv.getRuntime(); 111 InetAddress addr = InetAddress.getByName(hostname.convertToString().toString()); 112 ret[0] = r.newString(addr.getCanonicalHostName()); 113 ret[1] = r.newArray(); 114 ret[2] = r.newFixnum(2); ret[3] = r.newString(addr.getHostAddress()); 116 return r.newArrayNoCopy(ret); 117 } catch(UnknownHostException e) { 118 throw sockerr(recv, "gethostbyname: name or service not known"); 119 } 120 } 121 } | Popular Tags |