home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 July & August / Pcwk78a98.iso / Internet / Javadraw / DATA.Z / DatagramSocket.java < prev    next >
Text File  |  1997-08-30  |  10KB  |  298 lines

  1. /*
  2.  * @(#)DatagramSocket.java    1.25 97/02/22
  3.  * 
  4.  * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  * CopyrightVersion 1.1_beta
  20.  * 
  21.  */
  22.  
  23. package java.net;
  24.  
  25. import java.io.FileDescriptor;
  26. import java.io.IOException;
  27. import java.io.InterruptedIOException;
  28.  
  29. /**
  30.  * This class represents a socket for sending and receiving datagram packets.
  31.  * <p>
  32.  * A datagram socket is the sending or receiving point for a 
  33.  * connectionless packet delivery service. Each packet sent or 
  34.  * received on a datagram socket is individually addressed and 
  35.  * routed. Multiple packets sent from one machine to another may be 
  36.  * routed differently, and may arrive in any order. 
  37.  *
  38.  * @author  Pavani Diwanji
  39.  * @version 1.25, 02/22/97
  40.  * @see     java.net.DatagramPacket
  41.  * @since   JDK1.0
  42. */
  43. public
  44. class DatagramSocket {
  45.     /*
  46.      * The implementation of this DatagramSocket.
  47.      */
  48.     DatagramSocketImpl impl;
  49.  
  50.     /*
  51.      * The Class of DatagramSocketImpl we use for this runtime.  
  52.      */
  53.  
  54.     static Class implClass;
  55.  
  56.     static {
  57.     String prefix = "";
  58.     try {
  59.  
  60.         prefix = System.getProperty("impl.prefix", "Plain");
  61.  
  62.         implClass = Class.forName("java.net."+prefix+"DatagramSocketImpl");
  63.     } catch (Exception e) {
  64.         System.err.println("Can't find class: java.net." + prefix +
  65.                    "DatagramSocketImpl: check impl.prefix property");
  66.     }
  67.  
  68.     if (implClass == null) {
  69.         try {
  70.         implClass = Class.forName("java.net.PlainDatagramSocketImpl");
  71.         } catch (Exception e) {
  72.         throw new Error("System property impl.prefix incorrect");
  73.         }
  74.     }
  75.     }
  76.  
  77.     /**
  78.      * Constructs a datagram socket and binds it to any available port 
  79.      * on the local host machine. 
  80.      *
  81.      * @exception  SocketException  if the socket could not be opened,
  82.      *               or the socket could not bind to the specified local port.
  83.      * @since      JDK1.0
  84.      */
  85.     public DatagramSocket() throws SocketException {
  86.     // create a datagram socket.
  87.     create(0, null);
  88.     }
  89.  
  90.     /**
  91.      * Constructs a datagram socket and binds it to the specified port 
  92.      * on the local host machine. 
  93.      *
  94.      * @param      local   port to use.
  95.      * @exception  SocketException  if the socket could not be opened,
  96.      *               or the socket could not bind to the specified local port.
  97.      * @since      JDK1.0
  98.      */
  99.     public DatagramSocket(int port) throws SocketException {
  100.     this(port, null);
  101.     }
  102.  
  103.     /**
  104.      * Creates a datagram socket, bound to the specified local
  105.      * address.  The local port must be between 0 and 65535 inclusive.
  106.      * @param port local port to use
  107.      * @param laddr local address to bind
  108.      * @since   JDK1.1
  109.      */
  110.     public DatagramSocket(int port, InetAddress laddr) throws SocketException {
  111.     if (port < 0 || port > 0xFFFF)
  112.         throw new IllegalArgumentException("Port out of range:"+port);
  113.  
  114.     create(port, laddr);
  115.     }
  116.  
  117.     /* do the work of creating a vanilla datagramsocket.  It is
  118.      * important that the signature of this method not change,
  119.      * even though it is package-private since it is overridden by
  120.      * MulticastSocket, which must set SO_REUSEADDR.
  121.      */
  122.     void create(int port, InetAddress laddr) throws SocketException {
  123.     SecurityManager sec = System.getSecurityManager();
  124.     if (sec != null) {
  125.         sec.checkListen(port);
  126.     }
  127.     try {
  128.         impl = (DatagramSocketImpl) implClass.newInstance();
  129.     } catch (Exception e) {
  130.         throw new SocketException("can't instantiate DatagramSocketImpl");
  131.     }
  132.     // creates a udp socket
  133.     impl.create();
  134.     // binds the udp socket to desired port + address
  135.     if (laddr == null) {
  136.         laddr = InetAddress.anyLocalAddress;
  137.     }
  138.     impl.bind(port, laddr);
  139.     }
  140.  
  141.     /**
  142.      * Sends a datagram packet from this socket. The 
  143.      * <code>DatagramPacket</code> includes information indicating the 
  144.      * data to be sent, its length, the IP address of the remote host, 
  145.      * and the port number on the remote host. 
  146.      *
  147.      * @param      p   the <code>DatagramPacket</code> to be sent.
  148.      * @exception  IOException  if an I/O error occurs.
  149.      * @see        java.net.DatagramPacket
  150.      * @since      JDK1.0
  151.      */
  152.     public void send(DatagramPacket p) throws IOException  {
  153.  
  154.     // check the address is ok wiht the security manager on every send.
  155.     SecurityManager security = System.getSecurityManager();
  156.  
  157.     // The reason you want to synchronize on datagram packet
  158.     // is because you dont want an applet to change the address 
  159.     // while you are trying to send the packet for example 
  160.     // after the security check but before the send.
  161.     synchronized (p) {
  162.         if (security != null) {
  163.         if (p.getAddress().isMulticastAddress()) {
  164.             security.checkMulticast(p.getAddress());
  165.         } else {
  166.             security.checkConnect(p.getAddress().getHostAddress(), 
  167.                       p.getPort());
  168.         }
  169.         }
  170.             // call the  method to send
  171.             impl.send(p);
  172.         }
  173.     }
  174.  
  175.     /**
  176.      * Receives a datagram packet from this socket. When this method 
  177.      * returns, the <code>DatagramPacket</code>'s buffer is filled with 
  178.      * the data received. The datagram packet also contains the sender's 
  179.      * IP address, and the port number on the sender's machine. 
  180.      * <p>
  181.      * This method blocks until a datagram is received. The 
  182.      * <code>length</code> field of the datagram packet object contains 
  183.      * the length of the received message. If the message is longer than 
  184.      * the buffer length, the message is truncated. 
  185.      *
  186.      * @param      p   the <code>DatagramPacket</code> into which to place
  187.      *                 the incoming data.
  188.      * @exception  IOException  if an I/O error occurs.
  189.      * @see        java.net.DatagramPacket
  190.      * @see        java.net.DatagramSocket
  191.      * @since      JDK1.0
  192.      */
  193.     public synchronized void receive(DatagramPacket p) throws IOException {
  194.     // check the address is ok with the security manager before every recv.
  195.     SecurityManager security = System.getSecurityManager();
  196.  
  197.           synchronized (p) {
  198.         if (security != null) {
  199.  
  200.         while(true) {
  201.             // peek at the packet to see who it is from.
  202.             InetAddress peekAddress = new InetAddress();
  203.             int peekPort = impl.peek(peekAddress);
  204.  
  205.             try {
  206.             security.checkConnect(peekAddress.getHostAddress(), peekPort);
  207.             // security check succeeded - so now break and recv the packet.
  208.             break;
  209.             } catch (SecurityException se) {
  210.             // Throw away the offending packet by consuming
  211.             // it in a tmp buffer.
  212.             DatagramPacket tmp = new DatagramPacket(new byte[1], 1);
  213.             impl.receive(tmp);
  214.  
  215.                 // silently discard the offending packet and continue:
  216.             // unknown/malicious entities on nets should not make
  217.             // runtime throw security exception and disrupt the applet
  218.             // by sending random datagram packets.
  219.             continue;
  220.             } 
  221.         } // end of while
  222.         }
  223.         // If the security check succeeds, then receive the packet
  224.          impl.receive(p);
  225.     }    
  226.     }
  227.  
  228.     /**
  229.      * Gets the local address to which the socket is bound.
  230.      *
  231.      * @since   1.1
  232.      */
  233.     public InetAddress getLocalAddress() {
  234.     InetAddress in = null;
  235.     try {
  236.         in = (InetAddress) impl.getOption(SocketOptions.SO_BINDADDR);
  237.         SecurityManager s = System.getSecurityManager();
  238.         if (s != null) {
  239.         s.checkConnect(in.getHostAddress(), -1);
  240.         }
  241.     } catch (Exception e) {
  242.         in = InetAddress.anyLocalAddress; // "0.0.0.0"
  243.     }
  244.     return in;
  245.     }    
  246.  
  247.     /**
  248.      * Returns the port number on the local host to which this socket is bound.
  249.      *
  250.      * @return  the port number on the local host to which this socket is bound.
  251.      * @since   JDK1.0
  252.      */
  253.     public int getLocalPort() {
  254.     return impl.getLocalPort();
  255.     }
  256.  
  257.     /** Enable/disable SO_TIMEOUT with the specified timeout, in
  258.      *  milliseconds. With this option set to a non-zero timeout,
  259.      *  a call to receive() for this DatagramSocket
  260.      *  will block for only this amount of time.  If the timeout expires,
  261.      *  a <B>java.io.InterruptedIOException</B> is raised, though the
  262.      *  ServerSocket is still valid.  The option <B>must</B> be enabled
  263.      *  prior to entering the blocking operation to have effect.  The 
  264.      *  timeout must be > 0.
  265.      *  A timeout of zero is interpreted as an infinite timeout.  
  266.      *
  267.      * @since   JDK1.1
  268.      */
  269.     public synchronized void setSoTimeout(int timeout) throws SocketException {
  270.     impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
  271.     }
  272.  
  273.     /**
  274.      * Retrive setting for SO_TIMEOUT.  0 returns implies that the
  275.      * option is disabled (i.e., timeout of infinity).
  276.      *
  277.      * @since   JDK1.1
  278.      */
  279.     public synchronized int getSoTimeout() throws SocketException {
  280.     Object o = impl.getOption(SocketOptions.SO_TIMEOUT);
  281.     /* extra type safety */
  282.     if (o instanceof Integer) {
  283.         return ((Integer) o).intValue();
  284.     } else {
  285.         return 0;
  286.     }
  287.     }
  288.  
  289.     /**
  290.      * Closes this datagram socket. 
  291.      *
  292.      * @since   JDK1.0
  293.      */
  294.     public void close() {
  295.     impl.close();
  296.     }
  297. }
  298.