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