1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.net; 19 20 /** 21 * This class represents a datagram packet which contains data either to be sent 22 * or received through a {@code DatagramSocket}. It holds additional information 23 * such as its source or destination host. 24 * 25 * @see DatagramSocket 26 */ 27 public final class DatagramPacket { 28 29 private byte[] data; 30 31 /** 32 * Length of the data to be sent or size of data that was received via 33 * DatagramSocket#receive() method call. 34 */ 35 private int length; 36 37 /** 38 * The last user-supplied length (as opposed to a length set by simply receiving a packet). 39 * This length (unlike 'length') is sticky, and survives until the user sets another length. 40 * It's used to limit the amount of data that will be taken from future packets. 41 */ 42 private int userSuppliedLength; 43 44 private InetAddress address; 45 46 private int port = -1; // The default port number is -1 47 48 private int offset = 0; 49 50 /** 51 * Constructs a new {@code DatagramPacket} object to receive data up to 52 * {@code length} bytes. 53 * 54 * @param data 55 * a byte array to store the read characters. 56 * @param length 57 * the length of the data buffer. 58 */ DatagramPacket(byte[] data, int length)59 public DatagramPacket(byte[] data, int length) { 60 this(data, 0, length); 61 } 62 63 /** 64 * Constructs a new {@code DatagramPacket} object to receive data up to 65 * {@code length} bytes with a specified buffer offset. 66 * 67 * @param data 68 * a byte array to store the read characters. 69 * @param offset 70 * the offset of the byte array where the bytes is written. 71 * @param length 72 * the length of the data. 73 */ DatagramPacket(byte[] data, int offset, int length)74 public DatagramPacket(byte[] data, int offset, int length) { 75 setData(data, offset, length); 76 } 77 78 /** 79 * Constructs a new {@code DatagramPacket} object to send data to the port 80 * {@code aPort} of the address {@code host}. The {@code length} must be 81 * lesser than or equal to the size of {@code data}. The first {@code 82 * length} bytes from the byte array position {@code offset} are sent. 83 * 84 * @param data 85 * a byte array which stores the characters to be sent. 86 * @param offset 87 * the offset of {@code data} where to read from. 88 * @param length 89 * the length of data. 90 * @param host 91 * the address of the target host. 92 * @param aPort 93 * the port of the target host. 94 */ DatagramPacket(byte[] data, int offset, int length, InetAddress host, int aPort)95 public DatagramPacket(byte[] data, int offset, int length, InetAddress host, int aPort) { 96 this(data, offset, length); 97 setPort(aPort); 98 address = host; 99 } 100 101 /** 102 * Constructs a new {@code DatagramPacket} object to send data to the port 103 * {@code aPort} of the address {@code host}. The {@code length} must be 104 * lesser than or equal to the size of {@code data}. The first {@code 105 * length} bytes are sent. 106 * 107 * @param data 108 * a byte array which stores the characters to be sent. 109 * @param length 110 * the length of data. 111 * @param host 112 * the address of the target host. 113 * @param port 114 * the port of the target host. 115 */ DatagramPacket(byte[] data, int length, InetAddress host, int port)116 public DatagramPacket(byte[] data, int length, InetAddress host, int port) { 117 this(data, 0, length, host, port); 118 } 119 120 /** 121 * Gets the sender or destination IP address of this datagram packet. 122 * 123 * @return the address from where the datagram was received or to which it 124 * is sent. 125 */ getAddress()126 public synchronized InetAddress getAddress() { 127 return address; 128 } 129 130 /** 131 * Gets the data of this datagram packet. 132 * 133 * @return the received data or the data to be sent. 134 */ getData()135 public synchronized byte[] getData() { 136 return data; 137 } 138 139 /** 140 * Gets the length of the data stored in this datagram packet. 141 * 142 * @return the length of the received data or the data to be sent. 143 */ getLength()144 public synchronized int getLength() { 145 return length; 146 } 147 148 /** 149 * Gets the offset of the data stored in this datagram packet. 150 * 151 * @return the position of the received data or the data to be sent. 152 */ getOffset()153 public synchronized int getOffset() { 154 return offset; 155 } 156 157 /** 158 * Gets the port number of the target or sender host of this datagram 159 * packet. 160 * 161 * @return the port number of the origin or target host. 162 */ getPort()163 public synchronized int getPort() { 164 return port; 165 } 166 167 /** 168 * Sets the IP address of the target host. 169 * 170 * @param addr 171 * the target host address. 172 */ setAddress(InetAddress addr)173 public synchronized void setAddress(InetAddress addr) { 174 address = addr; 175 } 176 177 /** 178 * Sets the data buffer for this datagram packet. 179 */ setData(byte[] data, int offset, int byteCount)180 public synchronized void setData(byte[] data, int offset, int byteCount) { 181 if ((offset | byteCount) < 0 || offset > data.length || byteCount > data.length - offset) { 182 throw new IllegalArgumentException(); 183 } 184 this.data = data; 185 this.offset = offset; 186 this.length = byteCount; 187 this.userSuppliedLength = byteCount; 188 } 189 190 /** 191 * Sets the data buffer for this datagram packet. The length of the datagram 192 * packet is set to the buffer length. 193 * 194 * @param buf 195 * the buffer to store the data. 196 */ setData(byte[] buf)197 public synchronized void setData(byte[] buf) { 198 length = buf.length; // This will check for null 199 userSuppliedLength = length; 200 data = buf; 201 offset = 0; 202 } 203 204 /** 205 * Sets the length of the datagram packet. This length plus the offset must 206 * be lesser than or equal to the buffer size. 207 * 208 * @param length 209 * the length of this datagram packet. 210 */ setLength(int length)211 public synchronized void setLength(int length) { 212 if (length < 0 || offset + length > data.length) { 213 throw new IndexOutOfBoundsException("length=" + length + ", offset=" + offset + 214 ", buffer size=" + data.length); 215 } 216 this.length = length; 217 this.userSuppliedLength = length; 218 } 219 220 /** 221 * Resets 'length' to the last user-supplied length, ready to receive another packet. 222 * @hide for PlainDatagramSocketImpl 223 */ resetLengthForReceive()224 public void resetLengthForReceive() { 225 this.length = userSuppliedLength; 226 } 227 228 /** 229 * Sets 'length' without changing 'userSuppliedLength', after receiving a packet. 230 * @hide for IoBridge 231 */ setReceivedLength(int length)232 public void setReceivedLength(int length) { 233 this.length = length; 234 } 235 236 /** 237 * Sets the port number of the target host of this datagram packet. 238 * 239 * @param aPort 240 * the target host port number. 241 */ setPort(int aPort)242 public synchronized void setPort(int aPort) { 243 if (aPort < 0 || aPort > 65535) { 244 throw new IllegalArgumentException("Port out of range: " + aPort); 245 } 246 port = aPort; 247 } 248 249 /** 250 * Constructs a new {@code DatagramPacket} object to send data to the 251 * address {@code sockAddr}. The {@code length} must be lesser than or equal 252 * to the size of {@code data}. The first {@code length} bytes of the data 253 * are sent. 254 * 255 * @param data 256 * the byte array to store the data. 257 * @param length 258 * the length of the data. 259 * @param sockAddr 260 * the target host address and port. 261 * @throws SocketException 262 * if an error in the underlying protocol occurs. 263 */ DatagramPacket(byte[] data, int length, SocketAddress sockAddr)264 public DatagramPacket(byte[] data, int length, SocketAddress sockAddr) throws SocketException { 265 this(data, 0, length); 266 setSocketAddress(sockAddr); 267 } 268 269 /** 270 * Constructs a new {@code DatagramPacket} object to send data to the 271 * address {@code sockAddr}. The {@code length} must be lesser than or equal 272 * to the size of {@code data}. The first {@code length} bytes of the data 273 * are sent. 274 * 275 * @param data 276 * the byte array to store the data. 277 * @param offset 278 * the offset of the data. 279 * @param length 280 * the length of the data. 281 * @param sockAddr 282 * the target host address and port. 283 * @throws SocketException 284 * if an error in the underlying protocol occurs. 285 */ DatagramPacket(byte[] data, int offset, int length, SocketAddress sockAddr)286 public DatagramPacket(byte[] data, int offset, int length, 287 SocketAddress sockAddr) throws SocketException { 288 this(data, offset, length); 289 setSocketAddress(sockAddr); 290 } 291 292 /** 293 * Gets the host address and the port to which this datagram packet is sent 294 * as a {@code SocketAddress} object. 295 * 296 * @return the SocketAddress of the target host. 297 */ getSocketAddress()298 public synchronized SocketAddress getSocketAddress() { 299 return new InetSocketAddress(getAddress(), getPort()); 300 } 301 302 /** 303 * Sets the {@code SocketAddress} for this datagram packet. 304 * 305 * @param sockAddr 306 * the SocketAddress of the target host. 307 */ setSocketAddress(SocketAddress sockAddr)308 public synchronized void setSocketAddress(SocketAddress sockAddr) { 309 if (!(sockAddr instanceof InetSocketAddress)) { 310 throw new IllegalArgumentException("Socket address not an InetSocketAddress: " + 311 (sockAddr == null ? null : sockAddr.getClass())); 312 } 313 InetSocketAddress inetAddr = (InetSocketAddress) sockAddr; 314 if (inetAddr.isUnresolved()) { 315 throw new IllegalArgumentException("Socket address unresolved: " + sockAddr); 316 } 317 port = inetAddr.getPort(); 318 address = inetAddr.getAddress(); 319 } 320 } 321