1 28 package org.jruby.ext.socket; 29 30 import java.io.IOException ; 31 32 import java.net.BindException ; 33 import java.net.InetAddress ; 34 import java.net.InetSocketAddress ; 35 import java.net.UnknownHostException ; 36 37 import java.nio.channels.ServerSocketChannel ; 38 39 import org.jruby.Ruby; 40 import org.jruby.RubyClass; 41 import org.jruby.RubyFixnum; 42 import org.jruby.RubyNumeric; 43 import org.jruby.runtime.CallbackFactory; 44 import org.jruby.runtime.ObjectAllocator; 45 import org.jruby.runtime.builtin.IRubyObject; 46 47 50 public class RubyTCPServer extends RubyTCPSocket { 51 static void createTCPServer(Ruby runtime) { 52 RubyClass rb_cTCPServer = runtime.defineClass("TCPServer", runtime.getClass("TCPSocket"), TCPSERVER_ALLOCATOR); 53 CallbackFactory cfact = runtime.callbackFactory(RubyTCPServer.class); 54 55 rb_cTCPServer.defineFastMethod("initialize", cfact.getFastMethod("initialize",IRubyObject.class, IRubyObject.class)); 56 rb_cTCPServer.defineFastMethod("peeraddr", cfact.getFastOptMethod("peeraddr")); 57 rb_cTCPServer.defineFastMethod("getpeername", cfact.getFastOptMethod("getpeername")); 58 rb_cTCPServer.defineFastMethod("accept", cfact.getFastMethod("accept")); 59 rb_cTCPServer.defineFastMethod("close", cfact.getFastMethod("close")); 60 rb_cTCPServer.defineFastMethod("listen", cfact.getFastMethod("listen",IRubyObject.class)); 61 rb_cTCPServer.getMetaClass().defineFastMethod("open", cfact.getFastOptSingletonMethod("open")); 62 63 runtime.getObject().setConstant("TCPserver",rb_cTCPServer); 64 } 65 66 private static ObjectAllocator TCPSERVER_ALLOCATOR = new ObjectAllocator() { 67 public IRubyObject allocate(Ruby runtime, RubyClass klass) { 68 return new RubyTCPServer(runtime, klass); 69 } 70 }; 71 72 public RubyTCPServer(Ruby runtime, RubyClass type) { 73 super(runtime, type); 74 } 75 76 private ServerSocketChannel ssc; 77 private InetSocketAddress socket_address; 78 79 public IRubyObject initialize(IRubyObject hostname, IRubyObject port) { 80 if(hostname.isNil()) { 81 hostname = getRuntime().newString("0.0.0.0"); 82 } 83 String shost = hostname.convertToString().toString(); 84 try { 85 InetAddress addr = InetAddress.getByName(shost); 86 ssc = ServerSocketChannel.open(); 87 socket_address = new InetSocketAddress (addr, RubyNumeric.fix2int(port)); 88 ssc.socket().bind(socket_address); 89 setChannel(ssc); 90 } catch(UnknownHostException e) { 91 throw sockerr(this, "initialize: name or service not known"); 92 } catch(BindException e) { 93 throw getRuntime().newErrnoEADDRINUSEError(); 95 } catch(IOException e) { 96 throw sockerr(this, "initialize: name or service not known"); 97 } 98 99 return this; 100 } 101 102 public IRubyObject accept() { 103 RubyTCPSocket socket = new RubyTCPSocket(getRuntime(),getRuntime().getClass("TCPSocket")); 104 try { 105 socket.setChannel(ssc.accept()); 106 } catch(IOException e) { 107 throw sockerr(this, "problem when accepting"); 108 } 109 return socket; 110 } 111 112 public IRubyObject close() { 113 try { 114 ssc.close(); 115 } catch(IOException e) { 116 throw sockerr(this, "problem when closing"); 117 } 118 return getRuntime().getNil(); 119 } 120 121 public IRubyObject listen(IRubyObject backlog) { 122 return RubyFixnum.zero(getRuntime()); 123 } 124 125 public IRubyObject peeraddr(IRubyObject[] args) { 126 throw getRuntime().newNotImplementedError("not supported"); 127 } 128 129 public IRubyObject getpeername(IRubyObject[] args) { 130 throw getRuntime().newNotImplementedError("not supported"); 131 } 132 133 public static IRubyObject open(IRubyObject recv, IRubyObject[] args) { 134 return recv.callMethod(recv.getRuntime().getCurrentContext(),"new",args); 135 } 136 } | Popular Tags |