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.InetAddress;
24 import java.net.MulticastSocket;
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 * multicast datagram packets. It can be used to simulate packet loss.
34 *
35 * @author Alberto Montresor
36 * @author Hein Meling
37 * @since Jgroup 0.5
38 */
39 final class UnreliableMulticastSocket
40 extends MulticastSocket
41 {
42
43 ////////////////////////////////////////////////////////////////////////////////////////////
44 // Logger
45 ////////////////////////////////////////////////////////////////////////////////////////////
46
47 /** Obtain logger for this class */
48 private static final Logger log = Logger.getLogger(UnreliableMulticastSocket.class);
49
50
51 ////////////////////////////////////////////////////////////////////////////////////////////
52 // Fields
53 ////////////////////////////////////////////////////////////////////////////////////////////
54
55 private final SocketStatusImpl status;
56
57
58 ////////////////////////////////////////////////////////////////////////////////////////////
59 // Constructors
60 ////////////////////////////////////////////////////////////////////////////////////////////
61
62 /**
63 * Constructs an unreliable multicast socket and binds it to any
64 * available port on the local host machine.
65 *
66 * @exception SocketException
67 * If the socket could not be opened, or the socket could not
68 * be bound to the specified local port.
69 */
70 UnreliableMulticastSocket()
71 throws IOException
72 {
73 this(0);
74 }
75
76
77 /**
78 * Constructs a unreliable multicast socket and binds it to the
79 * specified port on the local host machine. The local port must be
80 * between 0 and 65535 inclusive.
81 *
82 * @param port
83 * Port to use on the local host.
84 * @exception SocketException
85 * If the socket could not be opened, or the socket could not
86 * be bound to the specified local port.
87 */
88 UnreliableMulticastSocket(int port)
89 throws IOException
90 {
91 super(port);
92 status = SocketStatusImpl.instance();
93 if (log.isDebugEnabled())
94 log.debug("UnreliableMulticastSocket initialized at port=" + port + ", status="+status);
95 }
96
97
98 ////////////////////////////////////////////////////////////////////////////////////////////
99 // Socket methods to override
100 ////////////////////////////////////////////////////////////////////////////////////////////
101
102 /**
103 * Sends a datagram packet using this socket. The specified
104 * <code>DatagramPacket</code> includes information indicating the
105 * data to be sent, its length, the IP address of the remote host,
106 * and the port number on the remote host.
107 *
108 * Note that in using the partition simulator, this method will
109 * only enable partitioning between hosts with separate multicast
110 * addresses. The partition pattern file must therefore define the
111 * link probabilities for multicast addresses rather than host
112 * addresses.
113 *
114 * @param packet
115 * The <code>DatagramPacket</code> to be sent.
116 * @exception IOException
117 * If an I/O error occurs.
118 * @see java.net.DatagramPacket
119 */
120 public void send(DatagramPacket packet)
121 throws IOException
122 {
123 // note that this receiver address is a multicast address
124 InetAddress receiver = packet.getAddress();
125 if (status == null || status.isReliable(receiver)) {
126 if (log.isDebugEnabled())
127 log.debug("Sending multicast packet to " + receiver.getHostAddress());
128 super.send(packet);
129 } else if (log.isDebugEnabled()) {
130 log.debug("Discarding multicast packet meant for " + receiver.getHostAddress());
131 }
132 }
133
134 /**
135 * Receive a datagram packet using this socket. The specified
136 * <code>DatagramPacket</code> should be filled with the received
137 * data, its length, the IP address and port of the sender host.
138 *
139 * Given that the partition simulator is activated for the link
140 * between the receiver and the sender, the packet size will be set
141 * to zero, and discarded in <code>MulticastNetworkInterface</code>.
142 *
143 * @param packet
144 * The <code>DatagramPacket</code> object to fill with the
145 * received data.
146 * @exception IOException
147 * If an I/O error occurs.
148 * @see java.net.DatagramPacket
149 */
150 public void receive(DatagramPacket packet)
151 throws IOException
152 {
153 super.receive(packet);
154 InetAddress sender = packet.getAddress();
155 if (log.isDebugEnabled()) {
156 log.debug("Received packet from: " + sender.getHostName());
157 log.debug("status=" + status + ", isReliable=" + status.isReliable(sender));
158 }
159 if (status != null && !status.isReliable(sender)) {
160 packet.setLength(0);
161 if (log.isDebugEnabled())
162 log.debug("Packet size set to zero; for discarding...");
163 }
164 }
165
166 } // END UnreliableMulticastSocket