1 7 8 package java.net; 9 10 import java.io.FileDescriptor ; 11 import java.io.IOException ; 12 import java.io.InterruptedIOException ; 13 import java.nio.channels.DatagramChannel ; 14 import java.security.AccessController ; 15 import java.security.PrivilegedExceptionAction ; 16 17 50 public 51 class DatagramSocket { 52 55 private boolean created = false; 56 private boolean bound = false; 57 private boolean closed = false; 58 private Object closeLock = new Object (); 59 60 63 DatagramSocketImpl impl; 64 65 68 boolean oldImpl = false; 69 70 76 static final int ST_NOT_CONNECTED = 0; 77 static final int ST_CONNECTED = 1; 78 static final int ST_CONNECTED_NO_IMPL = 2; 79 80 int connectState = ST_NOT_CONNECTED; 81 82 85 InetAddress connectedAddress = null; 86 int connectedPort = -1; 87 88 96 private synchronized void connectInternal(InetAddress address, int port) throws SocketException { 97 if (port < 0 || port > 0xFFFF) { 98 throw new IllegalArgumentException ("connect: " + port); 99 } 100 if (address == null) { 101 throw new IllegalArgumentException ("connect: null address"); 102 } 103 if (isClosed()) 104 return; 105 SecurityManager security = System.getSecurityManager(); 106 if (security != null) { 107 if (address.isMulticastAddress()) { 108 security.checkMulticast(address); 109 } else { 110 security.checkConnect(address.getHostAddress(), port); 111 security.checkAccept(address.getHostAddress(), port); 112 } 113 } 114 115 if (!isBound()) 116 bind(new InetSocketAddress (0)); 117 118 if (oldImpl) { 120 connectState = ST_CONNECTED_NO_IMPL; 121 } else { 122 try { 123 getImpl().connect(address, port); 124 125 connectState = ST_CONNECTED; 127 } catch (SocketException se) { 128 129 connectState = ST_CONNECTED_NO_IMPL; 131 } 132 } 133 134 connectedAddress = address; 135 connectedPort = port; 136 } 137 138 139 156 public DatagramSocket() throws SocketException { 157 createImpl(); 159 try { 160 bind(new InetSocketAddress (0)); 161 } catch (SocketException se) { 162 throw se; 163 } catch(IOException e) { 164 throw new SocketException (e.getMessage()); 165 } 166 } 167 168 176 protected DatagramSocket(DatagramSocketImpl impl) { 177 if (impl == null) 178 throw new NullPointerException (); 179 this.impl = impl; 180 checkOldImpl(); 181 } 182 183 206 public DatagramSocket(SocketAddress bindaddr) throws SocketException { 207 createImpl(); 209 if (bindaddr != null) { 210 bind(bindaddr); 211 } 212 } 213 214 233 public DatagramSocket(int port) throws SocketException { 234 this(port, null); 235 } 236 237 260 public DatagramSocket(int port, InetAddress laddr) throws SocketException { 261 this(new InetSocketAddress (laddr, port)); 262 } 263 264 private void checkOldImpl() { 265 if (impl == null) 266 return; 267 try { 270 AccessController.doPrivileged(new PrivilegedExceptionAction () { 271 public Object run() throws NoSuchMethodException { 272 Class [] cl = new Class [1]; 273 cl[0] = DatagramPacket .class; 274 impl.getClass().getDeclaredMethod("peekData", cl); 275 return null; 276 } 277 }); 278 } catch (java.security.PrivilegedActionException e) { 279 oldImpl = true; 280 } 281 } 282 283 static Class implClass = null; 284 285 void createImpl() throws SocketException { 286 if (impl == null) { 287 if (factory != null) { 288 impl = factory.createDatagramSocketImpl(); 289 checkOldImpl(); 290 } else { 291 if (implClass == null) { 292 String prefix = null; 293 try { 294 prefix = (String ) AccessController.doPrivileged( 295 new sun.security.action.GetPropertyAction("impl.prefix", "Plain")); 296 implClass = Class.forName("java.net."+prefix+"DatagramSocketImpl"); 297 } catch (Exception e) { 298 System.err.println("Can't find class: java.net." + 299 prefix + 300 "DatagramSocketImpl: check impl.prefix property"); 301 } 302 if (implClass == null) 303 implClass = java.net.PlainDatagramSocketImpl .class; 304 } 305 try { 306 impl = (DatagramSocketImpl ) implClass.newInstance(); 307 } catch (Exception e) { 308 throw new SocketException ("can't instantiate DatagramSocketImpl"); 309 } 310 if (!(impl instanceof java.net.PlainDatagramSocketImpl )) 313 checkOldImpl(); 314 } 315 } 316 impl.create(); 318 created = true; 319 } 320 321 330 DatagramSocketImpl getImpl() throws SocketException { 331 if (!created) 332 createImpl(); 333 return impl; 334 } 335 336 351 public synchronized void bind(SocketAddress addr) throws SocketException { 352 if (isClosed()) 353 throw new SocketException ("Socket is closed"); 354 if (isBound()) 355 throw new SocketException ("already bound"); 356 if (addr == null) 357 addr = new InetSocketAddress (0); 358 if (!(addr instanceof InetSocketAddress )) 359 throw new IllegalArgumentException ("Unsupported address type!"); 360 InetSocketAddress epoint = (InetSocketAddress ) addr; 361 if (epoint.isUnresolved()) 362 throw new SocketException ("Unresolved address"); 363 SecurityManager sec = System.getSecurityManager(); 364 if (sec != null) { 365 sec.checkListen(epoint.getPort()); 366 } 367 try { 368 getImpl().bind(epoint.getPort(), 369 epoint.getAddress()); 370 } catch (SocketException e) { 371 getImpl().close(); 372 throw e; 373 } 374 bound = true; 375 } 376 377 413 public void connect(InetAddress address, int port) { 414 try { 415 connectInternal(address, port); 416 } catch (SocketException se) { 417 throw new Error ("connect failed", se); 418 } 419 } 420 421 431 public void connect(SocketAddress addr) throws SocketException { 432 if (addr == null) 433 throw new IllegalArgumentException ("Address can't be null"); 434 if (!(addr instanceof InetSocketAddress )) 435 throw new IllegalArgumentException ("Unsupported address type"); 436 InetSocketAddress epoint = (InetSocketAddress ) addr; 437 if (epoint.isUnresolved()) 438 throw new SocketException ("Unresolved address"); 439 connectInternal(epoint.getAddress(), epoint.getPort()); 440 } 441 442 448 public void disconnect() { 449 synchronized (this) { 450 if (isClosed()) 451 return; 452 if (connectState == ST_CONNECTED) { 453 impl.disconnect (); 454 } 455 connectedAddress = null; 456 connectedPort = -1; 457 connectState = ST_NOT_CONNECTED; 458 } 459 } 460 461 467 public boolean isBound() { 468 return bound; 469 } 470 471 477 public boolean isConnected() { 478 return connectState != ST_NOT_CONNECTED; 479 } 480 481 487 public InetAddress getInetAddress() { 488 return connectedAddress; 489 } 490 491 497 public int getPort() { 498 return connectedPort; 499 } 500 501 512 public SocketAddress getRemoteSocketAddress() { 513 if (!isConnected()) 514 return null; 515 return new InetSocketAddress (getInetAddress(), getPort()); 516 } 517 518 529 530 public SocketAddress getLocalSocketAddress() { 531 if (!isBound()) 532 return null; 533 return new InetSocketAddress (getLocalAddress(), getLocalPort()); 534 } 535 536 574 public void send(DatagramPacket p) throws IOException { 575 InetAddress packetAddress = null; 576 synchronized (p) { 577 if (isClosed()) 578 throw new SocketException ("Socket is closed"); 579 if (connectState == ST_NOT_CONNECTED) { 580 SecurityManager security = System.getSecurityManager(); 582 583 if (security != null) { 588 if (p.getAddress().isMulticastAddress()) { 589 security.checkMulticast(p.getAddress()); 590 } else { 591 security.checkConnect(p.getAddress().getHostAddress(), 592 p.getPort()); 593 } 594 } 595 } else { 596 packetAddress = p.getAddress(); 598 if (packetAddress == null) { 599 p.setAddress(connectedAddress); 600 p.setPort(connectedPort); 601 } else if ((!packetAddress.equals(connectedAddress)) || 602 p.getPort() != connectedPort) { 603 throw new IllegalArgumentException ("connected address " + 604 "and packet address" + 605 " differ"); 606 } 607 } 608 if (!isBound()) 610 bind(new InetSocketAddress (0)); 611 getImpl().send(p); 613 } 614 } 615 616 647 public synchronized void receive(DatagramPacket p) throws IOException { 648 synchronized (p) { 649 if (!isBound()) 650 bind(new InetSocketAddress (0)); 651 if (connectState == ST_NOT_CONNECTED) { 652 SecurityManager security = System.getSecurityManager(); 654 if (security != null) { 655 while(true) { 656 String peekAd = null; 657 int peekPort = 0; 658 if (!oldImpl) { 660 DatagramPacket peekPacket = new DatagramPacket (new byte[1], 1); 662 peekPort = getImpl().peekData(peekPacket); 663 peekAd = peekPacket.getAddress().getHostAddress(); 664 } else { 665 InetAddress adr = new InetAddress (); 666 peekPort = getImpl().peek(adr); 667 peekAd = adr.getHostAddress(); 668 } 669 try { 670 security.checkAccept(peekAd, peekPort); 671 break; 674 } catch (SecurityException se) { 675 DatagramPacket tmp = new DatagramPacket (new byte[1], 1); 678 getImpl().receive(tmp); 679 680 continue; 687 } 688 } } 690 } 691 if (connectState == ST_CONNECTED_NO_IMPL) { 692 boolean stop = false; 696 while (!stop) { 697 InetAddress peekAddress = new InetAddress (); 699 int peekPort = getImpl().peek(peekAddress); 700 if ((!connectedAddress.equals(peekAddress)) || 701 (connectedPort != peekPort)) { 702 DatagramPacket tmp = new DatagramPacket (new byte[1], 1); 704 getImpl().receive(tmp); 705 } else { 706 stop = true; 707 } 708 } 709 } 710 getImpl().receive(p); 713 } 714 } 715 716 732 public InetAddress getLocalAddress() { 733 if (isClosed()) 734 return null; 735 InetAddress in = null; 736 try { 737 in = (InetAddress ) getImpl().getOption(SocketOptions.SO_BINDADDR); 738 if (in.isAnyLocalAddress()) { 739 in = InetAddress.anyLocalAddress(); 740 } 741 SecurityManager s = System.getSecurityManager(); 742 if (s != null) { 743 s.checkConnect(in.getHostAddress(), -1); 744 } 745 } catch (Exception e) { 746 in = InetAddress.anyLocalAddress(); } 748 return in; 749 } 750 751 756 public int getLocalPort() { 757 if (isClosed()) 758 return -1; 759 try { 760 return getImpl().getLocalPort(); 761 } catch (Exception e) { 762 return 0; 763 } 764 } 765 766 781 public synchronized void setSoTimeout(int timeout) throws SocketException { 782 if (isClosed()) 783 throw new SocketException ("Socket is closed"); 784 getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer (timeout)); 785 } 786 787 796 public synchronized int getSoTimeout() throws SocketException { 797 if (isClosed()) 798 throw new SocketException ("Socket is closed"); 799 if (getImpl() == null) 800 return 0; 801 Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT); 802 803 if (o instanceof Integer ) { 804 return ((Integer ) o).intValue(); 805 } else { 806 return 0; 807 } 808 } 809 810 839 public synchronized void setSendBufferSize(int size) 840 throws SocketException { 841 if (!(size > 0)) { 842 throw new IllegalArgumentException ("negative send size"); 843 } 844 if (isClosed()) 845 throw new SocketException ("Socket is closed"); 846 getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer (size)); 847 } 848 849 858 public synchronized int getSendBufferSize() throws SocketException { 859 if (isClosed()) 860 throw new SocketException ("Socket is closed"); 861 int result = 0; 862 Object o = getImpl().getOption(SocketOptions.SO_SNDBUF); 863 if (o instanceof Integer ) { 864 result = ((Integer )o).intValue(); 865 } 866 return result; 867 } 868 869 897 public synchronized void setReceiveBufferSize(int size) 898 throws SocketException { 899 if (size <= 0) { 900 throw new IllegalArgumentException ("invalid receive size"); 901 } 902 if (isClosed()) 903 throw new SocketException ("Socket is closed"); 904 getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer (size)); 905 } 906 907 915 public synchronized int getReceiveBufferSize() 916 throws SocketException { 917 if (isClosed()) 918 throw new SocketException ("Socket is closed"); 919 int result = 0; 920 Object o = getImpl().getOption(SocketOptions.SO_RCVBUF); 921 if (o instanceof Integer ) { 922 result = ((Integer )o).intValue(); 923 } 924 return result; 925 } 926 927 961 public synchronized void setReuseAddress(boolean on) throws SocketException { 962 if (isClosed()) 963 throw new SocketException ("Socket is closed"); 964 if (oldImpl) 966 getImpl().setOption(SocketOptions.SO_REUSEADDR, new Integer (on?-1:0)); 967 else 968 getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on)); 969 } 970 971 980 public synchronized boolean getReuseAddress() throws SocketException { 981 if (isClosed()) 982 throw new SocketException ("Socket is closed"); 983 Object o = getImpl().getOption(SocketOptions.SO_REUSEADDR); 984 return ((Boolean )o).booleanValue(); 985 } 986 987 995 public synchronized void setBroadcast(boolean on) throws SocketException { 996 if (isClosed()) 997 throw new SocketException ("Socket is closed"); 998 getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(on)); 999 } 1000 1001 1009 public synchronized boolean getBroadcast() throws SocketException { 1010 if (isClosed()) 1011 throw new SocketException ("Socket is closed"); 1012 return ((Boolean )(getImpl().getOption(SocketOptions.SO_BROADCAST))).booleanValue(); 1013 } 1014 1015 1051 public synchronized void setTrafficClass(int tc) throws SocketException { 1052 if (tc < 0 || tc > 255) 1053 throw new IllegalArgumentException ("tc is not in range 0 -- 255"); 1054 1055 if (isClosed()) 1056 throw new SocketException ("Socket is closed"); 1057 getImpl().setOption(SocketOptions.IP_TOS, new Integer (tc)); 1058 } 1059 1060 1076 public synchronized int getTrafficClass() throws SocketException { 1077 if (isClosed()) 1078 throw new SocketException ("Socket is closed"); 1079 return ((Integer )(getImpl().getOption(SocketOptions.IP_TOS))).intValue(); 1080 } 1081 1082 1094 public void close() { 1095 synchronized(closeLock) { 1096 if (isClosed()) 1097 return; 1098 impl.close(); 1099 closed = true; 1100 } 1101 } 1102 1103 1109 public boolean isClosed() { 1110 synchronized(closeLock) { 1111 return closed; 1112 } 1113 } 1114 1115 1129 public DatagramChannel getChannel() { 1130 return null; 1131 } 1132 1133 1136 static DatagramSocketImplFactory factory; 1137 1138 1166 public static synchronized void 1167 setDatagramSocketImplFactory(DatagramSocketImplFactory fac) 1168 throws IOException 1169 { 1170 if (factory != null) { 1171 throw new SocketException ("factory already defined"); 1172 } 1173 SecurityManager security = System.getSecurityManager(); 1174 if (security != null) { 1175 security.checkSetFactory(); 1176 } 1177 factory = fac; 1178 } 1179} 1180 | Popular Tags |