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 18package java.nio.channels; 19 20import java.io.IOException; 21import java.net.Socket; 22import java.net.SocketAddress; 23import java.nio.ByteBuffer; 24import java.nio.channels.spi.AbstractSelectableChannel; 25import java.nio.channels.spi.SelectorProvider; 26import java.util.Set; 27 28/** 29 * A {@code SocketChannel} is a selectable channel that provides a partial 30 * abstraction of stream connecting socket. 31 * 32 * The {@link #socket()} method returns a {@link Socket} instance which 33 * allows a wider range of socket operations than {@code SocketChannel} itself. 34 * 35 * <p>A socket channel is open but not connected when created by {@link #open}. 36 * After connecting it by calling {@link #connect(SocketAddress)}, it will remain 37 * connected until closed. 38 * 39 * <p>If the connection is non-blocking then 40 * {@link #connect(SocketAddress)} is used to initiate the connection, followed 41 * by a call of {@link #finishConnect} to perform the final steps of 42 * connecting. {@link #isConnectionPending} to tests whether we're still 43 * trying to connect; {@link #isConnected} tests whether the socket connect 44 * completed successfully. Note that realistic code should use a {@link Selector} 45 * instead of polling. Note also that {@link java.net.Socket} can connect with a 46 * timeout, which is the most common use for a non-blocking connect. 47 * 48 * <p>The input and output sides of a channel can be shut down independently and 49 * asynchronously without closing the channel. The {@link Socket#shutdownInput} method 50 * on the socket returned by {@link #socket} 51 * is used for the input side of a channel and subsequent read operations return 52 * -1, which means end of stream. If another thread is blocked in a read 53 * operation when the shutdown occurs, the read will end without effect and 54 * return end of stream. Likewise the {@link Socket#shutdownOutput} method is used for the 55 * output side of the channel; subsequent write operations throw a 56 * {@link ClosedChannelException}. If the output is shut down and another thread 57 * is blocked in a write operation, an {@link AsynchronousCloseException} will 58 * be thrown to the pending thread. 59 * 60 * <p>Socket channels are thread-safe, no more than one thread can read or write at 61 * any given time. The {@link #connect(SocketAddress)} and {@link 62 * #finishConnect()} methods are synchronized against each other; when they are 63 * processing, calls to {@link #read} and {@link #write} will block. 64 */ 65public abstract class SocketChannel extends AbstractSelectableChannel implements 66 ByteChannel, ScatteringByteChannel, GatheringByteChannel { 67 68 /** 69 * Constructs a new {@code SocketChannel}. 70 * 71 * @param selectorProvider 72 * an instance of SelectorProvider. 73 */ 74 protected SocketChannel(SelectorProvider selectorProvider) { 75 super(selectorProvider); 76 } 77 78 /** 79 * Creates an open and unconnected socket channel. 80 * <p> 81 * This channel is created by calling {@code openSocketChannel()} of the 82 * default {@link SelectorProvider} instance. 83 * 84 * @return the new channel which is open but unconnected. 85 * @throws IOException 86 * if an I/O error occurs. 87 */ 88 public static SocketChannel open() throws IOException { 89 return SelectorProvider.provider().openSocketChannel(); 90 } 91 92 /** 93 * Creates a socket channel and connects it to a socket address. 94 * <p> 95 * This method performs a call to {@code open()} followed by a call to 96 * {@code connect(SocketAddress)}. 97 * 98 * @param address 99 * the socket address to be connected to. 100 * @return the new connected channel. 101 * @throws AsynchronousCloseException 102 * if this channel is closed by another thread while this method 103 * is executing. 104 * @throws ClosedByInterruptException 105 * if another thread interrupts the calling thread while this 106 * operation is executing. The calling thread will have the 107 * interrupt state set and the channel will be closed. 108 * @throws UnresolvedAddressException 109 * if the address is not resolved. 110 * @throws UnsupportedAddressTypeException 111 * if the address type is not supported. 112 * @throws IOException 113 * if an I/O error occurs. 114 */ 115 public static SocketChannel open(SocketAddress address) throws IOException { 116 SocketChannel socketChannel = open(); 117 if (socketChannel != null) { 118 socketChannel.connect(address); 119 } 120 return socketChannel; 121 } 122 123 /** 124 * Gets the valid operations of this channel. Socket channels support 125 * connect, read and write operation, so this method returns 126 * {@code SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE}. 127 * 128 * @return the operations supported by this channel. 129 * @see java.nio.channels.SelectableChannel#validOps() 130 */ 131 @Override 132 public final int validOps() { 133 return (SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE); 134 } 135 136 /** 137 * Returns the socket assigned to this channel, which does not declare any public 138 * methods that are not declared in {@code Socket}. 139 * 140 * @return the socket assigned to this channel. 141 */ 142 public abstract Socket socket(); 143 144 /** 145 * Indicates whether this channel's socket is connected. 146 * 147 * @return {@code true} if this channel's socket is connected, {@code false} 148 * otherwise. 149 */ 150 public abstract boolean isConnected(); 151 152 /** 153 * Indicates whether this channel's socket is still trying to connect. 154 * 155 * @return {@code true} if the connection is initiated but not finished; 156 * {@code false} otherwise. 157 */ 158 public abstract boolean isConnectionPending(); 159 160 /** 161 * Connects this channel's socket with a remote address. 162 * <p> 163 * If this channel is blocking, this method will suspend until connecting is 164 * finished or an I/O exception occurs. If the channel is non-blocking, 165 * this method will return {@code true} if the connection is finished at 166 * once or return {@code false} when the connection must be finished later 167 * by calling {@code finishConnect()}. 168 * <p> 169 * This method can be called at any moment and can block other read and 170 * write operations while connecting. It executes the same security checks 171 * as the connect method of the {@code Socket} class. 172 * 173 * @param address 174 * the address to connect with. 175 * @return {@code true} if the connection is finished, {@code false} 176 * otherwise. 177 * @throws AlreadyConnectedException 178 * if the channel is already connected. 179 * @throws ConnectionPendingException 180 * a non-blocking connecting operation is already executing on 181 * this channel. 182 * @throws ClosedChannelException 183 * if this channel is closed. 184 * @throws AsynchronousCloseException 185 * if this channel is closed by another thread while this method 186 * is executing. 187 * @throws ClosedByInterruptException 188 * if another thread interrupts the calling thread while this 189 * operation is in progress. The calling thread will have the 190 * interrupt state set and this channel will be closed. 191 * @throws UnresolvedAddressException 192 * if the address is not resolved. 193 * @throws UnsupportedAddressTypeException 194 * if the address type is not supported. 195 * @throws IOException 196 * if an I/O error occurs. 197 */ 198 public abstract boolean connect(SocketAddress address) throws IOException; 199 200 /** 201 * Completes the connection process initiated by a call of {@code 202 * connect(SocketAddress)}. 203 * <p> 204 * This method returns {@code true} if the connection is finished already 205 * and returns {@code false} if the channel is non-blocking and the 206 * connection is not finished yet. 207 * <p> 208 * If this channel is in blocking mode, this method will suspend and return 209 * {@code true} when the connection is finished. It closes this channel and 210 * throws an exception if the connection fails. 211 * <p> 212 * This method can be called at any moment and it can block other {@code 213 * read} and {@code write} operations while connecting. 214 * 215 * @return {@code true} if the connection is successfully finished, {@code 216 * false} otherwise. 217 * @throws NoConnectionPendingException 218 * if the channel is not connected and the connection process 219 * has not been initiated. 220 * @throws ClosedChannelException 221 * if this channel is closed. 222 * @throws AsynchronousCloseException 223 * if this channel is closed by another thread while this method 224 * is executing. 225 * @throws ClosedByInterruptException 226 * if another thread interrupts the calling thread while this 227 * operation is in progress. The calling thread has the 228 * interrupt state set, and this channel is closed. 229 * @throws IOException 230 * if an I/O error occurs. 231 */ 232 public abstract boolean finishConnect() throws IOException; 233 234 /** 235 * Reads bytes from this socket channel into the given buffer. 236 * <p> 237 * The maximum number of bytes that will be read is the remaining number of 238 * bytes in the buffer when the method is invoked. The bytes will be copied 239 * into the buffer starting at the buffer's current position. 240 * <p> 241 * The call may block if other threads are also attempting to read from this 242 * channel. 243 * <p> 244 * Upon completion, the buffer's position is set to the end of the bytes 245 * that have been read. The buffer's limit is not changed. 246 * 247 * @param target 248 * the byte buffer to receive the bytes. 249 * @return the number of bytes actually read. 250 * @throws AsynchronousCloseException 251 * if another thread closes the channel during the read. 252 * @throws NotYetConnectedException 253 * if this channel is not yet connected. 254 * @throws ClosedByInterruptException 255 * if another thread interrupts the calling thread while this 256 * operation is in progress. The interrupt state of the calling 257 * thread is set and the channel is closed. 258 * @throws ClosedChannelException 259 * if this channel is closed. 260 * @throws IOException 261 * if another I/O error occurs. 262 * @see java.nio.channels.ReadableByteChannel#read(java.nio.ByteBuffer) 263 */ 264 public abstract int read(ByteBuffer target) throws IOException; 265 266 /** 267 * Reads bytes from this socket channel into a subset of the given buffers. 268 * This method attempts to read all {@code remaining()} bytes from {@code 269 * length} byte buffers, in order, starting at {@code targets[offset]}. The 270 * number of bytes actually read is returned. 271 * <p> 272 * If a read operation is in progress, subsequent threads will block until 273 * the read is completed and will then contend for the ability to read. 274 * 275 * @param targets 276 * the array of byte buffers into which the bytes will be copied. 277 * @param offset 278 * the index of the first buffer to store bytes in. 279 * @param length 280 * the maximum number of buffers to store bytes in. 281 * @return the number of bytes actually read. 282 * @throws AsynchronousCloseException 283 * if this channel is closed by another thread during this read 284 * operation. 285 * @throws ClosedByInterruptException 286 * if another thread interrupts the calling thread while this 287 * operation is in progress. The interrupt state of the calling 288 * thread is set and the channel is closed. 289 * @throws ClosedChannelException 290 * if this channel is closed. 291 * @throws IndexOutOfBoundsException 292 * if {@code offset < 0} or {@code length < 0}, or if {@code 293 * offset + length} is greater than the size of {@code targets}. 294 * @throws IOException 295 * if another I/O error occurs. 296 * @throws NotYetConnectedException 297 * if this channel is not yet connected. 298 * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[], 299 * int, int) 300 */ 301 public abstract long read(ByteBuffer[] targets, int offset, int length) throws IOException; 302 303 /** 304 * Reads bytes from this socket channel and stores them in the specified 305 * array of buffers. This method attempts to read as many bytes as can be 306 * stored in the buffer array from this channel and returns the number of 307 * bytes actually read. 308 * <p> 309 * If a read operation is in progress, subsequent threads will block until 310 * the read is completed and will then contend for the ability to read. 311 * <p> 312 * Calling this method is equivalent to calling {@code read(targets, 0, 313 * targets.length);} 314 * 315 * @param targets 316 * the array of byte buffers into which the bytes will be copied. 317 * @return the number of bytes actually read. 318 * @throws AsynchronousCloseException 319 * if this channel is closed by another thread during this read 320 * operation. 321 * @throws ClosedByInterruptException 322 * if another thread interrupts the calling thread while this 323 * operation is in progress. The interrupt state of the calling 324 * thread is set and the channel is closed. 325 * @throws ClosedChannelException 326 * if this channel is closed. 327 * @throws IOException 328 * if another I/O error occurs. 329 * @throws NotYetConnectedException 330 * if this channel is not yet connected. 331 */ 332 public synchronized final long read(ByteBuffer[] targets) throws IOException { 333 return read(targets, 0, targets.length); 334 } 335 336 /** 337 * Writes bytes from the given byte buffer to this socket channel. The 338 * maximum number of bytes that are written is the remaining number of bytes 339 * in the buffer when this method is invoked. The bytes are taken from the 340 * buffer starting at the buffer's position. 341 * <p> 342 * The call may block if other threads are also attempting to write to the 343 * same channel. 344 * <p> 345 * Upon completion, the buffer's position is updated to the end of the bytes 346 * that have been written. The buffer's limit is not changed. 347 * 348 * @param source 349 * the byte buffer containing the bytes to be written. 350 * @return the number of bytes actually written. 351 * @throws AsynchronousCloseException 352 * if another thread closes the channel during the write. 353 * @throws ClosedByInterruptException 354 * if another thread interrupts the calling thread while this 355 * operation is in progress. The interrupt state of the calling 356 * thread is set and the channel is closed. 357 * @throws ClosedChannelException 358 * if the channel was already closed. 359 * @throws IOException 360 * if another I/O error occurs. 361 * @throws NotYetConnectedException 362 * if this channel is not connected yet. 363 * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer) 364 */ 365 public abstract int write(ByteBuffer source) throws IOException; 366 367 /** 368 * Attempts to write a subset of the given bytes from the buffers to this 369 * socket channel. This method attempts to write all {@code remaining()} 370 * bytes from {@code length} byte buffers, in order, starting at {@code 371 * sources[offset]}. The number of bytes actually written is returned. 372 * <p> 373 * If a write operation is in progress, subsequent threads will block until 374 * the write is completed and then contend for the ability to write. 375 * 376 * @param sources 377 * the array of byte buffers that is the source for bytes written 378 * to this channel. 379 * @param offset 380 * the index of the first buffer in {@code buffers }to get bytes 381 * from. 382 * @param length 383 * the number of buffers to get bytes from. 384 * @return the number of bytes actually written to this channel. 385 * @throws AsynchronousCloseException 386 * if this channel is closed by another thread during this write 387 * operation. 388 * @throws ClosedByInterruptException 389 * if another thread interrupts the calling thread while this 390 * operation is in progress. The interrupt state of the calling 391 * thread is set and the channel is closed. 392 * @throws ClosedChannelException 393 * if this channel is closed. 394 * @throws IndexOutOfBoundsException 395 * if {@code offset < 0} or {@code length < 0}, or if {@code 396 * offset + length} is greater than the size of {@code sources}. 397 * @throws IOException 398 * if another I/O error occurs. 399 * @throws NotYetConnectedException 400 * if this channel is not yet connected. 401 * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[], 402 * int, int) 403 */ 404 public abstract long write(ByteBuffer[] sources, int offset, int length) throws IOException; 405 406 /** 407 * Writes bytes from all the given byte buffers to this socket channel. 408 * <p> 409 * Calling this method is equivalent to calling {@code write(sources, 0, 410 * sources.length);} 411 * 412 * @param sources 413 * the buffers containing bytes to write. 414 * @return the number of bytes actually written. 415 * @throws AsynchronousCloseException 416 * if this channel is closed by another thread during this write 417 * operation. 418 * @throws ClosedByInterruptException 419 * if another thread interrupts the calling thread while this 420 * operation is in progress. The interrupt state of the calling 421 * thread is set and the channel is closed. 422 * @throws ClosedChannelException 423 * if this channel is closed. 424 * @throws IOException 425 * if another I/O error occurs. 426 * @throws NotYetConnectedException 427 * if this channel is not yet connected. 428 * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[]) 429 */ 430 public synchronized final long write(ByteBuffer[] sources) throws IOException { 431 return write(sources, 0, sources.length); 432 } 433} 434