View Javadoc

1   /*
2    * Copyright (c) 1998-2002 The Jgroup Team.
3    *
4    * This program is free software; you can redistribute it and/or modify
5    * it under the terms of the GNU Lesser General Public License version 2 as
6    * published by the Free Software Foundation.
7    *
8    * This program is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   * GNU Lesser General Public License for more details.
12   *
13   * You should have received a copy of the GNU Lesser General Public License
14   * along with this program; if not, write to the Free Software
15   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16   *
17   */
18  
19  package jgroup.relacs.mss;
20  
21  import java.io.IOException;
22  import java.net.DatagramPacket;
23  import java.net.DatagramSocket;
24  import java.net.InetAddress;
25  import java.net.SocketException;
26  
27  import jgroup.relacs.simulator.SocketStatusImpl;
28  
29  import org.apache.log4j.Logger;
30  
31  /**
32   *  This class represents an unreliable socket for sending and receiving
33   *  datagram packets.  It can be used to simulate packet loss.
34   *
35   *  @author Alberto Montresor
36   *  @since Jgroup 0.5
37   */
38  final class UnreliableDatagramSocket
39    extends DatagramSocket
40  {
41  
42    ////////////////////////////////////////////////////////////////////////////////////////////
43    // Logger
44    ////////////////////////////////////////////////////////////////////////////////////////////
45  
46    /** Obtain logger for this class */
47    private static final Logger log = Logger.getLogger(UnreliableDatagramSocket.class);
48  
49  
50    ////////////////////////////////////////////////////////////////////////////////////////////
51    // Fields
52    ////////////////////////////////////////////////////////////////////////////////////////////
53  
54    private SocketStatusImpl status;
55  
56  
57    ////////////////////////////////////////////////////////////////////////////////////////////
58    // Constructors
59    ////////////////////////////////////////////////////////////////////////////////////////////
60  
61    /**
62     *  Constructs an unreliable datagram socket and binds it to any
63     *  available port on the local host machine.
64     *
65     *  @exception SocketException
66     *    If the socket could not be opened, or the socket could not
67     *    be bound to the specified local port.
68     */
69    UnreliableDatagramSocket()
70      throws SocketException
71    {
72      this(0, null);
73    }
74  
75  
76    /**
77     *  Constructs a unreliable datagram socket and binds it to the
78     *  specified port on the local host machine.
79     *
80     *  @param port
81     *    Port to use on the local host.
82     *  @exception SocketException
83     *    If the socket could not be opened, or the socket could not
84     *    be bound to the specified local port.
85     */
86    UnreliableDatagramSocket(int port)
87      throws SocketException
88    {
89      this(port, null);
90    }
91  
92  
93    /**
94     *  Constructs a unreliable datagram socket, bound to the specified
95     *  local address, and binds it to the specified port on the local
96     *  host machine.  The local port must be between 0 and 65535
97     *  inclusive.
98     *
99     *  @param port
100    *    Port to use on the local host.
101    *  @param localAddr
102    *    The local address to bind the socket to.
103    *  @exception SocketException
104    *    If the socket could not be opened, or the socket could not
105    *    be bound to the specified local port.
106    */
107   UnreliableDatagramSocket(int port, InetAddress localAddr)
108     throws SocketException
109   {
110     super(port, localAddr);
111     status = SocketStatusImpl.instance();
112     if (log.isDebugEnabled())
113       log.debug("UnreliableDatagramSocket initialized at port=" + port + ", status="+status);
114   }
115 
116 
117   ////////////////////////////////////////////////////////////////////////////////////////////
118   // Socket methods to override
119   ////////////////////////////////////////////////////////////////////////////////////////////
120 
121   /**
122    *  Sends a datagram packet using this socket.  The specified
123    *  <code>DatagramPacket</code> includes information indicating the
124    *  data to be sent, its length, the IP address of the remote host,
125    *  and the port number on the remote host.
126    *  
127    *  This method overrides the DatagramSocket implementation, and
128    *  checks if the packet receiver address is reachable (through the
129    *  partition simulator) from the local host.  If the packet receiver
130    *  is unreachable the packet is not sent, otherwise if the receiver
131    *  is reachable the packet is sent.
132    *
133    *  @param packet
134    *    The <code>DatagramPacket</code> to be sent.
135    *  @exception IOException
136    *    If an I/O error occurs.
137    *  @see java.net.DatagramPacket
138    */
139   public void send(DatagramPacket packet)
140     throws IOException
141   {
142     InetAddress receiver = packet.getAddress();
143     if (status == null || status.isReliable(receiver)) {
144       if (log.isDebugEnabled())
145         log.debug("Sending packet to " + receiver.getHostName());
146       super.send(packet);
147     } else if (log.isDebugEnabled()) {
148       log.debug("Discarding packet meant for " + receiver.getHostName());
149     }
150   }
151 
152 } // END UnreliableDatagramSocket