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