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 871 public void setSoLinger(boolean on, int linger) throws SocketException { 872 if (isClosed()) 873 throw new SocketException ("Socket is closed"); 874 if (!on) { 875 getImpl().setOption(SocketOptions.SO_LINGER, new Boolean (on)); 876 } else { 877 if (linger < 0) { 878 throw new IllegalArgumentException ("invalid value for SO_LINGER"); 879 } 880 if (linger > 65535) 881 linger = 65535; 882 getImpl().setOption(SocketOptions.SO_LINGER, new Integer (linger)); 883 } 884 } 885 886 898 public int getSoLinger() throws SocketException { 899 if (isClosed()) 900 throw new SocketException ("Socket is closed"); 901 Object o = getImpl().getOption(SocketOptions.SO_LINGER); 902 if (o instanceof Integer ) { 903 return ((Integer ) o).intValue(); 904 } else { 905 return -1; 906 } 907 } 908 909 919 public void sendUrgentData (int data) throws IOException { 920 if (!getImpl().supportsUrgentData ()) { 921 throw new SocketException ("Urgent data not supported"); 922 } 923 getImpl().sendUrgentData (data); 924 } 925 926 949 public void setOOBInline(boolean on) throws SocketException { 950 if (isClosed()) 951 throw new SocketException ("Socket is closed"); 952 getImpl().setOption(SocketOptions.SO_OOBINLINE, Boolean.valueOf(on)); 953 } 954 955 964 public boolean getOOBInline() throws SocketException { 965 if (isClosed()) 966 throw new SocketException ("Socket is closed"); 967 return ((Boolean ) getImpl().getOption(SocketOptions.SO_OOBINLINE)).booleanValue(); 968 } 969 970 986 public synchronized void setSoTimeout(int timeout) throws SocketException { 987 if (isClosed()) 988 throw new SocketException ("Socket is closed"); 989 if (timeout < 0) 990 throw new IllegalArgumentException ("timeout can't be negative"); 991 992 getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer (timeout)); 993 } 994 995 1004 public synchronized int getSoTimeout() throws SocketException { 1005 if (isClosed()) 1006 throw new SocketException ("Socket is closed"); 1007 Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT); 1008 1009 if (o instanceof Integer ) { 1010 return ((Integer ) o).intValue(); 1011 } else { 1012 return 0; 1013 } 1014 } 1015 1016 1038 public synchronized void setSendBufferSize(int size) 1039 throws SocketException { 1040 if (!(size > 0)) { 1041 throw new IllegalArgumentException ("negative send size"); 1042 } 1043 if (isClosed()) 1044 throw new SocketException ("Socket is closed"); 1045 getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer (size)); 1046 } 1047 1048 1060 public synchronized int getSendBufferSize() throws SocketException { 1061 if (isClosed()) 1062 throw new SocketException ("Socket is closed"); 1063 int result = 0; 1064 Object o = getImpl().getOption(SocketOptions.SO_SNDBUF); 1065 if (o instanceof Integer ) { 1066 result = ((Integer )o).intValue(); 1067 } 1068 return result; 1069 } 1070 1071 1110 public synchronized void setReceiveBufferSize(int size) 1111 throws SocketException { 1112 if (size <= 0) { 1113 throw new IllegalArgumentException ("invalid receive size"); 1114 } 1115 if (isClosed()) 1116 throw new SocketException ("Socket is closed"); 1117 getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer (size)); 1118 } 1119 1120 1131 public synchronized int getReceiveBufferSize() 1132 throws SocketException { 1133 if (isClosed()) 1134 throw new SocketException ("Socket is closed"); 1135 int result = 0; 1136 Object o = getImpl().getOption(SocketOptions.SO_RCVBUF); 1137 if (o instanceof Integer ) { 1138 result = ((Integer )o).intValue(); 1139 } 1140 return result; 1141 } 1142 1143 1152 public void setKeepAlive(boolean on) throws SocketException { 1153 if (isClosed()) 1154 throw new SocketException ("Socket is closed"); 1155 getImpl().setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(on)); 1156 } 1157 1158 1167 public boolean getKeepAlive() throws SocketException { 1168 if (isClosed()) 1169 throw new SocketException ("Socket is closed"); 1170 return ((Boolean ) getImpl().getOption(SocketOptions.SO_KEEPALIVE)).booleanValue(); 1171 } 1172 1173 1209 public void setTrafficClass(int tc) throws SocketException { 1210 if (tc < 0 || tc > 255) 1211 throw new IllegalArgumentException ("tc is not in range 0 -- 255"); 1212 1213 if (isClosed()) 1214 throw new SocketException ("Socket is closed"); 1215 getImpl().setOption(SocketOptions.IP_TOS, new Integer (tc)); 1216 } 1217 1218 1233 public int getTrafficClass() throws SocketException { 1234 return ((Integer ) (getImpl().getOption(SocketOptions.IP_TOS))).intValue(); 1235 } 1236 1237 1271 public void setReuseAddress(boolean on) throws SocketException { 1272 if (isClosed()) 1273 throw new SocketException ("Socket is closed"); 1274 getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on)); 1275 } 1276 1277 1286 public boolean getReuseAddress() throws SocketException { 1287 if (isClosed()) 1288 throw new SocketException ("Socket is closed"); 1289 return ((Boolean ) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue(); 1290 } 1291 1292 1310 public synchronized void close() throws IOException { 1311 synchronized(closeLock) { 1312 if (isClosed()) 1313 return; 1314 if (created) 1315 impl.close(); 1316 closed = true; 1317 } 1318 } 1319 1320 1337 public void shutdownInput() throws IOException 1338 { 1339 if (isClosed()) 1340 throw new SocketException ("Socket is closed"); 1341 if (!isConnected()) 1342 throw new SocketException ("Socket is not connected"); 1343 if (isInputShutdown()) 1344 throw new SocketException ("Socket input is already shutdown"); 1345 getImpl().shutdownInput(); 1346 shutIn = true; 1347 } 1348 1349 1367 public void shutdownOutput() throws IOException 1368 { 1369 if (isClosed()) 1370 throw new SocketException ("Socket is closed"); 1371 if (!isConnected()) 1372 throw new SocketException ("Socket is not connected"); 1373 if (isOutputShutdown()) 1374 throw new SocketException ("Socket output is already shutdown"); 1375 getImpl().shutdownOutput(); 1376 shutOut = true; 1377 } 1378 1379 1384 public String toString() { 1385 try { 1386 if (isConnected()) 1387 return "Socket[addr=" + getImpl().getInetAddress() + 1388 ",port=" + getImpl().getPort() + 1389 ",localport=" + getImpl().getLocalPort() + "]"; 1390 } catch (SocketException e) { 1391 } 1392 return "Socket[unconnected]"; 1393 } 1394 1395 1401 public boolean isConnected() { 1402 return connected || oldImpl; 1404 } 1405 1406 1413 public boolean isBound() { 1414 return bound || oldImpl; 1416 } 1417 1418 1425 public boolean isClosed() { 1426 synchronized(closeLock) { 1427 return closed; 1428 } 1429 } 1430 1431 1438 public boolean isInputShutdown() { 1439 return shutIn; 1440 } 1441 1442 1449 public boolean isOutputShutdown() { 1450 return shutOut; 1451 } 1452 1453 1456 private static SocketImplFactory factory = null; 1457 1458 1482 public static synchronized void setSocketImplFactory(SocketImplFactory fac) 1483 throws IOException 1484 { 1485 if (factory != null) { 1486 throw new SocketException ("factory already defined"); 1487 } 1488 SecurityManager security = System.getSecurityManager(); 1489 if (security != null) { 1490 security.checkSetFactory(); 1491 } 1492 factory = fac; 1493 } 1494 1495 1533 public void setPerformancePreferences(int connectionTime, 1534 int latency, 1535 int bandwidth) 1536 { 1537 1538 } 1539} 1540 | Popular Tags |