1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 package java.net;
28 
29 /**
30  * This class represents a datagram packet.
31  * <p>
32  * Datagram packets are used to implement a connectionless packet
33  * delivery service. Each message is routed from one machine to
34  * another based solely on information contained within that packet.
35  * Multiple packets sent from one machine to another might be routed
36  * differently, and might arrive in any order. Packet delivery is
37  * not guaranteed.
38  *
39  * @author  Pavani Diwanji
40  * @author  Benjamin Renaud
41  * @since   JDK1.0
42  */
43 public final
44 class DatagramPacket {
45 
46     // Android-removed: init method has been removed
47     // /**
48     //  * Perform class initialization
49     //  */
50     // static {
51     //     init();
52     // }
53 
54     /*
55      * The fields of this class are package-private since DatagramSocketImpl
56      * classes needs to access them.
57      */
58     byte[] buf;
59     int offset;
60     int length;
61     int bufLength;
62     InetAddress address;
63     int port;
64 
65     /**
66      * Constructs a {@code DatagramPacket} for receiving packets of
67      * length {@code length}, specifying an offset into the buffer.
68      * <p>
69      * The {@code length} argument must be less than or equal to
70      * {@code buf.length}.
71      *
72      * @param   buf      buffer for holding the incoming datagram.
73      * @param   offset   the offset for the buffer
74      * @param   length   the number of bytes to read.
75      *
76      * @since 1.2
77      */
DatagramPacket(byte buf[], int offset, int length)78     public DatagramPacket(byte buf[], int offset, int length) {
79         setData(buf, offset, length);
80         this.address = null;
81         this.port = -1;
82     }
83 
84     /**
85      * Constructs a {@code DatagramPacket} for receiving packets of
86      * length {@code length}.
87      * <p>
88      * The {@code length} argument must be less than or equal to
89      * {@code buf.length}.
90      *
91      * @param   buf      buffer for holding the incoming datagram.
92      * @param   length   the number of bytes to read.
93      */
DatagramPacket(byte buf[], int length)94     public DatagramPacket(byte buf[], int length) {
95         this (buf, 0, length);
96     }
97 
98     /**
99      * Constructs a datagram packet for sending packets of length
100      * {@code length} with offset {@code ioffset}to the
101      * specified port number on the specified host. The
102      * {@code length} argument must be less than or equal to
103      * {@code buf.length}.
104      *
105      * @param   buf      the packet data.
106      * @param   offset   the packet data offset.
107      * @param   length   the packet data length.
108      * @param   address  the destination address.
109      * @param   port     the destination port number.
110      * @see java.net.InetAddress
111      *
112      * @since 1.2
113      */
DatagramPacket(byte buf[], int offset, int length, InetAddress address, int port)114     public DatagramPacket(byte buf[], int offset, int length,
115                           InetAddress address, int port) {
116         setData(buf, offset, length);
117         setAddress(address);
118         setPort(port);
119     }
120 
121     // Android-changed: Added Android-specific notes regarding the exception signature change.
122     /**
123      * Constructs a datagram packet for sending packets of length
124      * {@code length} with offset {@code ioffset}to the
125      * specified port number on the specified host. The
126      * {@code length} argument must be less than or equal to
127      * {@code buf.length}.
128      *
129      * <p>
130      * <em>Android note</em>: Up to and including API 25 this method declared that a SocketException
131      * can be thrown, although the exception is never thrown. Code compiled against a newer SDK does
132      * not need to catch the exception and will be binary compatible with older versions of Android.
133      *
134      * @param   buf      the packet data.
135      * @param   offset   the packet data offset.
136      * @param   length   the packet data length.
137      * @param   address  the destination socket address.
138      * @throws  IllegalArgumentException if address type is not supported
139      * @see java.net.InetAddress
140      *
141      * @since 1.4
142      */
DatagramPacket(byte buf[], int offset, int length, SocketAddress address)143     public DatagramPacket(byte buf[], int offset, int length, SocketAddress address) {
144         setData(buf, offset, length);
145         setSocketAddress(address);
146     }
147 
148     // Android-changed: Added Android-specific notes regarding the exception signature change.
149     /**
150      * Constructs a datagram packet for sending packets of length
151      * {@code length} to the specified port number on the specified
152      * host. The {@code length} argument must be less than or equal
153      * to {@code buf.length}.
154      *
155      * <p>
156      * <em>Android note</em>: Up to and including API 25 this method declared that a SocketException
157      * can be thrown, although the exception is never thrown. Code compiled against a newer SDK does
158      * not need to catch the exception and will be binary compatible with older versions of Android.
159      *
160      * @param   buf      the packet data.
161      * @param   length   the packet length.
162      * @param   address  the destination address.
163      * @param   port     the destination port number.
164      * @see     java.net.InetAddress
165      */
DatagramPacket(byte buf[], int length, InetAddress address, int port)166     public DatagramPacket(byte buf[], int length,
167                           InetAddress address, int port) {
168         this(buf, 0, length, address, port);
169     }
170 
171     /**
172      * Constructs a datagram packet for sending packets of length
173      * {@code length} to the specified port number on the specified
174      * host. The {@code length} argument must be less than or equal
175      * to {@code buf.length}.
176      *
177      * @param   buf      the packet data.
178      * @param   length   the packet length.
179      * @param   address  the destination address.
180      * @throws  IllegalArgumentException if address type is not supported
181      * @since 1.4
182      * @see     java.net.InetAddress
183      */
DatagramPacket(byte buf[], int length, SocketAddress address)184     public DatagramPacket(byte buf[], int length, SocketAddress address) {
185         this(buf, 0, length, address);
186     }
187 
188     /**
189      * Returns the IP address of the machine to which this datagram is being
190      * sent or from which the datagram was received.
191      *
192      * @return  the IP address of the machine to which this datagram is being
193      *          sent or from which the datagram was received.
194      * @see     java.net.InetAddress
195      * @see #setAddress(java.net.InetAddress)
196      */
getAddress()197     public synchronized InetAddress getAddress() {
198         return address;
199     }
200 
201     /**
202      * Returns the port number on the remote host to which this datagram is
203      * being sent or from which the datagram was received.
204      *
205      * @return  the port number on the remote host to which this datagram is
206      *          being sent or from which the datagram was received.
207      * @see #setPort(int)
208      */
getPort()209     public synchronized int getPort() {
210         return port;
211     }
212 
213     /**
214      * Returns the data buffer. The data received or the data to be sent
215      * starts from the {@code offset} in the buffer,
216      * and runs for {@code length} long.
217      *
218      * @return  the buffer used to receive or  send data
219      * @see #setData(byte[], int, int)
220      */
getData()221     public synchronized byte[] getData() {
222         return buf;
223     }
224 
225     /**
226      * Returns the offset of the data to be sent or the offset of the
227      * data received.
228      *
229      * @return  the offset of the data to be sent or the offset of the
230      *          data received.
231      *
232      * @since 1.2
233      */
getOffset()234     public synchronized int getOffset() {
235         return offset;
236     }
237 
238     /**
239      * Returns the length of the data to be sent or the length of the
240      * data received.
241      *
242      * @return  the length of the data to be sent or the length of the
243      *          data received.
244      * @see #setLength(int)
245      */
getLength()246     public synchronized int getLength() {
247         return length;
248     }
249 
250     /**
251      * Set the data buffer for this packet. This sets the
252      * data, length and offset of the packet.
253      *
254      * @param buf the buffer to set for this packet
255      *
256      * @param offset the offset into the data
257      *
258      * @param length the length of the data
259      *       and/or the length of the buffer used to receive data
260      *
261      * @exception NullPointerException if the argument is null
262      *
263      * @see #getData
264      * @see #getOffset
265      * @see #getLength
266      *
267      * @since 1.2
268      */
setData(byte[] buf, int offset, int length)269     public synchronized void setData(byte[] buf, int offset, int length) {
270         /* this will check to see if buf is null */
271         if (length < 0 || offset < 0 ||
272             (length + offset) < 0 ||
273             ((length + offset) > buf.length)) {
274             throw new IllegalArgumentException("illegal length or offset");
275         }
276         this.buf = buf;
277         this.length = length;
278         this.bufLength = length;
279         this.offset = offset;
280     }
281 
282     /**
283      * Sets the IP address of the machine to which this datagram
284      * is being sent.
285      * @param iaddr the {@code InetAddress}
286      * @since   JDK1.1
287      * @see #getAddress()
288      */
setAddress(InetAddress iaddr)289     public synchronized void setAddress(InetAddress iaddr) {
290         address = iaddr;
291     }
292 
293     // BEGIN Android-changed
294     /**
295      * Sets 'length' without changing 'userSuppliedLength', after receiving a packet.
296      * @hide for IoBridge
297      */
setReceivedLength(int length)298     public void setReceivedLength(int length) {
299         this.length = length;
300     }
301     // END Android-changed
302 
303     /**
304      * Sets the port number on the remote host to which this datagram
305      * is being sent.
306      * @param iport the port number
307      * @since   JDK1.1
308      * @see #getPort()
309      */
setPort(int iport)310     public synchronized void setPort(int iport) {
311         if (iport < 0 || iport > 0xFFFF) {
312             throw new IllegalArgumentException("Port out of range:"+ iport);
313         }
314         port = iport;
315     }
316 
317     /**
318      * Sets the SocketAddress (usually IP address + port number) of the remote
319      * host to which this datagram is being sent.
320      *
321      * @param address the {@code SocketAddress}
322      * @throws  IllegalArgumentException if address is null or is a
323      *          SocketAddress subclass not supported by this socket
324      *
325      * @since 1.4
326      * @see #getSocketAddress
327      */
setSocketAddress(SocketAddress address)328     public synchronized void setSocketAddress(SocketAddress address) {
329         if (address == null || !(address instanceof InetSocketAddress))
330             throw new IllegalArgumentException("unsupported address type");
331         InetSocketAddress addr = (InetSocketAddress) address;
332         if (addr.isUnresolved())
333             throw new IllegalArgumentException("unresolved address");
334         setAddress(addr.getAddress());
335         setPort(addr.getPort());
336     }
337 
338     /**
339      * Gets the SocketAddress (usually IP address + port number) of the remote
340      * host that this packet is being sent to or is coming from.
341      *
342      * @return the {@code SocketAddress}
343      * @since 1.4
344      * @see #setSocketAddress
345      */
getSocketAddress()346     public synchronized SocketAddress getSocketAddress() {
347         return new InetSocketAddress(getAddress(), getPort());
348     }
349 
350     /**
351      * Set the data buffer for this packet. With the offset of
352      * this DatagramPacket set to 0, and the length set to
353      * the length of {@code buf}.
354      *
355      * @param buf the buffer to set for this packet.
356      *
357      * @exception NullPointerException if the argument is null.
358      *
359      * @see #getLength
360      * @see #getData
361      *
362      * @since JDK1.1
363      */
setData(byte[] buf)364     public synchronized void setData(byte[] buf) {
365         if (buf == null) {
366             throw new NullPointerException("null packet buffer");
367         }
368         this.buf = buf;
369         this.offset = 0;
370         this.length = buf.length;
371         this.bufLength = buf.length;
372     }
373 
374     /**
375      * Set the length for this packet. The length of the packet is
376      * the number of bytes from the packet's data buffer that will be
377      * sent, or the number of bytes of the packet's data buffer that
378      * will be used for receiving data. The length must be lesser or
379      * equal to the offset plus the length of the packet's buffer.
380      *
381      * @param length the length to set for this packet.
382      *
383      * @exception IllegalArgumentException if the length is negative
384      * of if the length is greater than the packet's data buffer
385      * length.
386      *
387      * @see #getLength
388      * @see #setData
389      *
390      * @since JDK1.1
391      */
setLength(int length)392     public synchronized void setLength(int length) {
393         if ((length + offset) > buf.length || length < 0 ||
394             (length + offset) < 0) {
395             throw new IllegalArgumentException("illegal length");
396         }
397         this.length = length;
398         this.bufLength = this.length;
399     }
400 
401     // Android-removed: JNI has been removed
402     // /**
403     //  * Perform class load-time initializations.
404     //  */
405     // private native static void init();
406 }
407