1 7 8 package java.net; 9 10 import java.io.FileDescriptor ; 11 import java.io.IOException ; 12 import java.nio.channels.ServerSocketChannel ; 13 import java.security.AccessController ; 14 import java.security.PrivilegedExceptionAction ; 15 16 34 public 35 class ServerSocket { 36 39 private boolean created = false; 40 private boolean bound = false; 41 private boolean closed = false; 42 private Object closeLock = new Object (); 43 44 47 private SocketImpl impl; 48 49 52 private boolean oldImpl = false; 53 54 60 public ServerSocket() throws IOException { 61 setImpl(); 62 } 63 64 96 public ServerSocket(int port) throws IOException { 97 this(port, 50, null); 98 } 99 100 140 public ServerSocket(int port, int backlog) throws IOException { 141 this(port, backlog, null); 142 } 143 144 177 public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException { 178 setImpl(); 179 if (port < 0 || port > 0xFFFF) 180 throw new IllegalArgumentException ( 181 "Port value out of range: " + port); 182 if (backlog < 1) 183 backlog = 50; 184 try { 185 bind(new InetSocketAddress (bindAddr, port), backlog); 186 } catch(SecurityException e) { 187 close(); 188 throw e; 189 } catch(IOException e) { 190 close(); 191 throw e; 192 } 193 } 194 195 203 SocketImpl getImpl() throws SocketException { 204 if (!created) 205 createImpl(); 206 return impl; 207 } 208 209 private void checkOldImpl() { 210 if (impl == null) 211 return; 212 try { 215 AccessController.doPrivileged(new PrivilegedExceptionAction () { 216 public Object run() throws NoSuchMethodException { 217 Class [] cl = new Class [2]; 218 cl[0] = SocketAddress .class; 219 cl[1] = Integer.TYPE; 220 impl.getClass().getDeclaredMethod("connect", cl); 221 return null; 222 } 223 }); 224 } catch (java.security.PrivilegedActionException e) { 225 oldImpl = true; 226 } 227 } 228 229 private void setImpl() { 230 if (factory != null) { 231 impl = factory.createSocketImpl(); 232 checkOldImpl(); 233 } else { 234 impl = new SocksSocketImpl (); 237 } 238 if (impl != null) 239 impl.setServerSocket(this); 240 } 241 242 248 void createImpl() throws SocketException { 249 if (impl == null) 250 setImpl(); 251 try { 252 impl.create(true); 253 created = true; 254 } catch (IOException e) { 255 throw new SocketException (e.getMessage()); 256 } 257 } 258 259 276 public void bind(SocketAddress endpoint) throws IOException { 277 bind(endpoint, 50); 278 } 279 280 301 public void bind(SocketAddress endpoint, int backlog) throws IOException { 302 if (isClosed()) 303 throw new SocketException ("Socket is closed"); 304 if (!oldImpl && isBound()) 305 throw new SocketException ("Already bound"); 306 if (endpoint == null) 307 endpoint = new InetSocketAddress (0); 308 if (!(endpoint instanceof InetSocketAddress )) 309 throw new IllegalArgumentException ("Unsupported address type"); 310 InetSocketAddress epoint = (InetSocketAddress ) endpoint; 311 if (epoint.isUnresolved()) 312 throw new SocketException ("Unresolved address"); 313 if (backlog < 1) 314 backlog = 50; 315 try { 316 SecurityManager security = System.getSecurityManager(); 317 if (security != null) 318 security.checkListen(epoint.getPort()); 319 getImpl().bind(epoint.getAddress(), epoint.getPort()); 320 getImpl().listen(backlog); 321 bound = true; 322 } catch(SecurityException e) { 323 bound = false; 324 throw e; 325 } catch(IOException e) { 326 bound = false; 327 throw e; 328 } 329 } 330 331 337 public InetAddress getInetAddress() { 338 if (!isBound()) 339 return null; 340 try { 341 return getImpl().getInetAddress(); 342 } catch (SocketException e) { 343 } 347 return null; 348 } 349 350 356 public int getLocalPort() { 357 if (!isBound()) 358 return -1; 359 try { 360 return getImpl().getLocalPort(); 361 } catch (SocketException e) { 362 } 366 return -1; 367 } 368 369 380 381 public SocketAddress getLocalSocketAddress() { 382 if (!isBound()) 383 return null; 384 return new InetSocketAddress (getInetAddress(), getLocalPort()); 385 } 386 387 415 public Socket accept() throws IOException { 416 if (isClosed()) 417 throw new SocketException ("Socket is closed"); 418 if (!isBound()) 419 throw new SocketException ("Socket is not bound yet"); 420 Socket s = new Socket ((SocketImpl ) null); 421 implAccept(s); 422 return s; 423 } 424 425 441 protected final void implAccept(Socket s) throws IOException { 442 SocketImpl si = null; 443 try { 444 if (s.impl == null) 445 s.setImpl(); 446 si = s.impl; 447 s.impl = null; 448 si.address = new InetAddress (); 449 si.fd = new FileDescriptor (); 450 getImpl().accept(si); 451 452 SecurityManager security = System.getSecurityManager(); 453 if (security != null) { 454 security.checkAccept(si.getInetAddress().getHostAddress(), 455 si.getPort()); 456 } 457 } catch (IOException e) { 458 if (si != null) 459 si.reset(); 460 s.impl = si; 461 throw e; 462 } catch (SecurityException e) { 463 if (si != null) 464 si.reset(); 465 s.impl = si; 466 throw e; 467 } 468 s.impl = si; 469 s.postAccept(); 470 } 471 472 485 public void close() throws IOException { 486 synchronized(closeLock) { 487 if (isClosed()) 488 return; 489 if (created) 490 impl.close(); 491 closed = true; 492 } 493 } 494 495 511 public ServerSocketChannel getChannel() { 512 return null; 513 } 514 515 521 public boolean isBound() { 522 return bound || oldImpl; 524 } 525 526 532 public boolean isClosed() { 533 synchronized(closeLock) { 534 return closed; 535 } 536 } 537 538 554 public synchronized void setSoTimeout(int timeout) throws SocketException { 555 if (isClosed()) 556 throw new SocketException ("Socket is closed"); 557 getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer (timeout)); 558 } 559 560 568 public synchronized int getSoTimeout() throws IOException { 569 if (isClosed()) 570 throw new SocketException ("Socket is closed"); 571 Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT); 572 573 if (o instanceof Integer ) { 574 return ((Integer ) o).intValue(); 575 } else { 576 return 0; 577 } 578 } 579 580 616 public void setReuseAddress(boolean on) throws SocketException { 617 if (isClosed()) 618 throw new SocketException ("Socket is closed"); 619 getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on)); 620 } 621 622 631 public boolean getReuseAddress() throws SocketException { 632 if (isClosed()) 633 throw new SocketException ("Socket is closed"); 634 return ((Boolean ) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue(); 635 } 636 637 643 public String toString() { 644 if (!isBound()) 645 return "ServerSocket[unbound]"; 646 return "ServerSocket[addr=" + impl.getInetAddress() + 647 ",port=" + impl.getPort() + 648 ",localport=" + impl.getLocalPort() + "]"; 649 } 650 651 void setBound() { 652 bound = true; 653 } 654 655 void setCreated() { 656 created = true; 657 } 658 659 662 private static SocketImplFactory factory = null; 663 664 689 public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException { 690 if (factory != null) { 691 throw new SocketException ("factory already defined"); 692 } 693 SecurityManager security = System.getSecurityManager(); 694 if (security != null) { 695 security.checkSetFactory(); 696 } 697 factory = fac; 698 } 699 700 735 public synchronized void setReceiveBufferSize (int size) throws SocketException { 736 if (!(size > 0)) { 737 throw new IllegalArgumentException ("negative receive size"); 738 } 739 if (isClosed()) 740 throw new SocketException ("Socket is closed"); 741 getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer (size)); 742 } 743 744 757 public synchronized int getReceiveBufferSize() 758 throws SocketException { 759 if (isClosed()) 760 throw new SocketException ("Socket is closed"); 761 int result = 0; 762 Object o = getImpl().getOption(SocketOptions.SO_RCVBUF); 763 if (o instanceof Integer ) { 764 result = ((Integer )o).intValue(); 765 } 766 return result; 767 } 768 769 807 public void setPerformancePreferences(int connectionTime, 808 int latency, 809 int bandwidth) 810 { 811 812 } 813 814 } 815 | Popular Tags |