| 1 7 8 package java.net; 9 10 import java.io.InputStream ; 11 import java.io.OutputStream ; 12 import java.io.IOException ; 13 import java.io.InterruptedIOException ; 14 import java.nio.channels.SocketChannel ; 15 import java.security.AccessController ; 16 import java.security.PrivilegedExceptionAction ; 17 import java.security.PrivilegedAction ; 18 19 37 public 38 class Socket { 39 42 private boolean created = false; 43 private boolean bound = false; 44 private boolean connected = false; 45 private boolean closed = false; 46 private Object closeLock = new Object (); 47 private boolean shutIn = false; 48 private boolean shutOut = false; 49 50 53 SocketImpl impl; 54 55 58 private boolean oldImpl = false; 59 60 67 public Socket() { 68 setImpl(); 69 } 70 71 99 public Socket(Proxy proxy) { 100 if (proxy != null && proxy.type() == Proxy.Type.SOCKS) { 101 SecurityManager security = System.getSecurityManager(); 102 InetSocketAddress epoint = (InetSocketAddress ) proxy.address(); 103 if (security != null) { 104 if (epoint.isUnresolved()) 105 epoint = new InetSocketAddress (epoint.getHostName(), epoint.getPort()); 106 if (epoint.isUnresolved()) 107 security.checkConnect(epoint.getHostName(), epoint.getPort()); 108 else 109 security.checkConnect(epoint.getAddress().getHostAddress(), 110 epoint.getPort()); 111 } 112 impl = new SocksSocketImpl (proxy); 113 impl.setSocket(this); 114 } else { 115 if (proxy == Proxy.NO_PROXY) { 116 if (factory == null) { 117 impl = new PlainSocketImpl (); 118 impl.setSocket(this); 119 } else 120 setImpl(); 121 } else 122 throw new IllegalArgumentException ("Invalid Proxy"); 123 } 124 } 125 126 137 protected Socket(SocketImpl impl) throws SocketException { 138 this.impl = impl; 139 if (impl != null) { 140 checkOldImpl(); 141 this.impl.setSocket(this); 142 } 143 } 144 145 177 public Socket(String host, int port) 178 throws UnknownHostException , IOException  179 { 180 this(host != null ? new InetSocketAddress (host, port) : 181 new InetSocketAddress (InetAddress.getByName(null), port), 182 new InetSocketAddress (0), true); 183 } 184 185 208 public Socket(InetAddress address, int port) throws IOException { 209 this(address != null ? new InetSocketAddress (address, port) : null, 210 new InetSocketAddress (0), true); 211 } 212 213 238 public Socket(String host, int port, InetAddress localAddr, 239 int localPort) throws IOException { 240 this(host != null ? new InetSocketAddress (host, port) : 241 new InetSocketAddress (InetAddress.getByName(null), port), 242 new InetSocketAddress (localAddr, localPort), true); 243 } 244 245 265 public Socket(InetAddress address, int port, InetAddress localAddr, 266 int localPort) throws IOException { 267 this(address != null ? new InetSocketAddress (address, port) : null, 268 new InetSocketAddress (localAddr, localPort), true); 269 } 270 271 308 @Deprecated  309 public Socket(String host, int port, boolean stream) throws IOException { 310 this(host != null ? new InetSocketAddress (host, port) : 311 new InetSocketAddress (InetAddress.getByName(null), port), 312 new InetSocketAddress (0), stream); 313 } 314 315 347 @Deprecated  348 public Socket(InetAddress host, int port, boolean stream) throws IOException { 349 this(host != null ? new InetSocketAddress (host, port) : null, 350 new InetSocketAddress (0), stream); 351 } 352 353 private Socket(SocketAddress address, SocketAddress localAddr, 354 boolean stream) throws IOException { 355 setImpl(); 356 357 if (address == null) 359 throw new NullPointerException (); 360 361 try { 362 createImpl(stream); 363 if (localAddr == null) 364 localAddr = new InetSocketAddress (0); 365 bind(localAddr); 366 if (address != null) 367 connect(address); 368 } catch (IOException e) { 369 close(); 370 throw e; 371 } 372 } 373 374 382 void createImpl(boolean stream) throws SocketException { 383 if (impl == null) 384 setImpl(); 385 try { 386 impl.create(stream); 387 created = true; 388 } catch (IOException e) { 389 throw new SocketException (e.getMessage()); 390 } 391 } 392 393 private void checkOldImpl() { 394 if (impl == null) 395 return; 396 399 Boolean tmpBool = (Boolean ) AccessController.doPrivileged (new PrivilegedAction () { 400 public Boolean run() { 401 Class [] cl = new Class [2]; 402 cl[0] = SocketAddress .class; 403 cl[1] = Integer.TYPE; 404 Class clazz = impl.getClass(); 405 while (true) { 406 try { 407 clazz.getDeclaredMethod("connect", cl); 408 return Boolean.FALSE; 409 } catch (NoSuchMethodException e) { 410 clazz = clazz.getSuperclass(); 411 if (clazz.equals(java.net.SocketImpl .class)) { 415 return Boolean.TRUE; 416 } 417 } 418 } 419 } 420 }); 421 oldImpl = tmpBool.booleanValue(); 422 } 423 424 428 void setImpl() { 429 if (factory != null) { 430 impl = factory.createSocketImpl(); 431 checkOldImpl(); 432 } else { 433 impl = new SocksSocketImpl (); 436 } 437 if (impl != null) 438 impl.setSocket(this); 439 } 440 441 442 450 SocketImpl getImpl() throws SocketException { 451 if (!created) 452 createImpl(true); 453 return impl; 454 } 455 456 469 public void connect(SocketAddress endpoint) throws IOException { 470 connect(endpoint, 0); 471 } 472 473 490 public void connect(SocketAddress endpoint, int timeout) throws IOException { 491 if (endpoint == null) 492 throw new IllegalArgumentException ("connect: The address can't be null"); 493 494 if (timeout < 0) 495 throw new IllegalArgumentException ("connect: timeout can't be negative"); 496 497 if (isClosed()) 498 throw new SocketException ("Socket is closed"); 499 500 if (!oldImpl && isConnected()) 501 throw new SocketException ("already connected"); 502 503 if (!(endpoint instanceof InetSocketAddress )) 504 throw new IllegalArgumentException ("Unsupported address type"); 505 506 InetSocketAddress epoint = (InetSocketAddress ) endpoint; 507 508 SecurityManager security = System.getSecurityManager(); 509 if (security != null) { 510 if (epoint.isUnresolved()) 511 security.checkConnect(epoint.getHostName(), 512 epoint.getPort()); 513 else 514 security.checkConnect(epoint.getAddress().getHostAddress(), 515 epoint.getPort()); 516 } 517 if (!created) 518 createImpl(true); 519 if (!oldImpl) 520 impl.connect(epoint, timeout); 521 else if (timeout == 0) { 522 if (epoint.isUnresolved()) 523 impl.connect(epoint.getAddress().getHostName(), 524 epoint.getPort()); 525 else 526 impl.connect(epoint.getAddress(), epoint.getPort()); 527 } else 528 throw new UnsupportedOperationException ("SocketImpl.connect(addr, timeout)"); 529 connected = true; 530 534 bound = true; 535 } 536 537 552 public void bind(SocketAddress bindpoint) throws IOException { 553 if (isClosed()) 554 throw new SocketException ("Socket is closed"); 555 if (!oldImpl && isBound()) 556 throw new SocketException ("Already bound"); 557 558 if (bindpoint != null && (!(bindpoint instanceof InetSocketAddress ))) 559 throw new IllegalArgumentException ("Unsupported address type"); 560 InetSocketAddress epoint = (InetSocketAddress ) bindpoint; 561 if (epoint != null && epoint.isUnresolved()) 562 throw new SocketException ("Unresolved address"); 563 if (bindpoint == null) 564 getImpl().bind(InetAddress.anyLocalAddress(), 0); 565 else 566 getImpl().bind(epoint.getAddress(), 567 epoint.getPort()); 568 bound = true; 569 } 570 571 574 final void postAccept() { 575 connected = true; 576 created = true; 577 bound = true; 578 } 579 580 void setCreated() { 581 created = true; 582 } 583 584 void setBound() { 585 bound = true; 586 } 587 588 void setConnected() { 589 connected = true; 590 } 591 592 598 public InetAddress getInetAddress() { 599 if (!isConnected()) 600 return null; 601 try { 602 return getImpl().getInetAddress(); 603 } catch (SocketException e) { 604 } 605 return null; 606 } 607 608 616 public InetAddress getLocalAddress() { 617 if (!isBound()) 619 return InetAddress.anyLocalAddress(); 620 InetAddress in = null; 621 try { 622 in = (InetAddress ) getImpl().getOption(SocketOptions.SO_BINDADDR); 623 if (in.isAnyLocalAddress()) { 624 in = InetAddress.anyLocalAddress(); 625 } 626 } catch (Exception e) { 627 in = InetAddress.anyLocalAddress(); } 629 return in; 630 } 631 632 638 public int getPort() { 639 if (!isConnected()) 640 return 0; 641 try { 642 return getImpl().getPort(); 643 } catch (SocketException e) { 644 } 646 return -1; 647 } 648 649 655 public int getLocalPort() { 656 if (!isBound()) 657 return -1; 658 try { 659 return getImpl().getLocalPort(); 660 } catch(SocketException e) { 661 } 663 return -1; 664 } 665 666 677 public SocketAddress getRemoteSocketAddress() { 678 if (!isConnected()) 679 return null; 680 return new InetSocketAddress (getInetAddress(), getPort()); 681 } 682 683 694 695 public SocketAddress getLocalSocketAddress() { 696 if (!isBound()) 697 return null; 698 return new InetSocketAddress (getLocalAddress(), getLocalPort()); 699 } 700 701 718 public SocketChannel getChannel() { 719 return null; 720 } 721 722 764 public InputStream getInputStream() throws IOException { 765 if (isClosed()) 766 throw new SocketException ("Socket is closed"); 767 if (!isConnected()) 768 throw new SocketException ("Socket is not connected"); 769 if (isInputShutdown()) 770 throw new SocketException ("Socket input is shutdown"); 771 final Socket s = this; 772 InputStream is = null; 773 try { 774 is = (InputStream ) 775 AccessController.doPrivileged(new PrivilegedExceptionAction () { 776 public Object run() throws IOException { 777 return impl.getInputStream(); 778 } 779 }); 780 } catch (java.security.PrivilegedActionException e) { 781 throw (IOException ) e.getException(); 782 } 783 return is; 784 } 785 786 801 public OutputStream getOutputStream() throws IOException { 802 if (isClosed()) 803 throw new SocketException ("Socket is closed"); 804 if (!isConnected()) 805 throw new SocketException ("Socket is not connected"); 806 if (isOutputShutdown()) 807 throw new SocketException ("Socket output is shutdown"); 808 final Socket s = this; 809 OutputStream os = null; 810 try { 811 os = (OutputStream ) 812 AccessController.doPrivileged(new PrivilegedExceptionAction () { 813 public Object run() throws IOException { 814 return impl.getOutputStream(); 815 } 816 }); 817 } catch (java.security.PrivilegedActionException e) { 818 throw (IOException ) e.getException(); 819 } 820 return os; 821 } 822 823 836 public void setTcpNoDelay(boolean on) throws SocketException { 837 if (isClosed()) 838 throw new SocketException ("Socket is closed"); 839 getImpl().setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on)); 840 } 841 842 851 public boolean getTcpNoDelay() throws SocketException { 852 if (isClosed()) 853 throw new SocketException ("Socket is closed"); 854 return ((Boolean ) getImpl().getOption(SocketOptions.TCP_NODELAY)).booleanValue(); 855 } 856 857 |