1 /* 2 * Copyright 2012 The Netty Project 3 * 4 * The Netty Project licenses this file to you under the Apache License, 5 * version 2.0 (the "License"); you may not use this file except in compliance 6 * with the License. You may obtain a copy of the License at: 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 package org.jboss.netty.channel; 17 18 import java.net.InetSocketAddress; 19 import java.net.SocketAddress; 20 import java.nio.channels.NotYetConnectedException; 21 import java.nio.channels.SelectionKey; 22 23 import org.jboss.netty.channel.socket.DatagramChannel; 24 import org.jboss.netty.channel.socket.ServerSocketChannel; 25 import org.jboss.netty.channel.socket.SocketChannel; 26 import org.jboss.netty.channel.socket.nio.NioSocketChannelConfig; 27 28 29 /** 30 * A nexus to a network socket or a component which is capable of I/O 31 * operations such as read, write, connect, and bind. 32 * <p> 33 * A channel provides a user: 34 * <ul> 35 * <li>the current state of the channel (e.g. is it open? is it connected?),</li> 36 * <li>the {@linkplain ChannelConfig configuration parameters} of the channel (e.g. receive buffer size),</li> 37 * <li>the I/O operations that the channel supports (e.g. read, write, connect, and bind), and</li> 38 * <li>the {@link ChannelPipeline} which handles all {@linkplain ChannelEvent I/O events and requests} 39 * associated with the channel.</li> 40 * </ul> 41 * 42 * <h3>All I/O operations are asynchronous.</h3> 43 * <p> 44 * All I/O operations in Netty are asynchronous. It means any I/O calls will 45 * return immediately with no guarantee that the requested I/O operation has 46 * been completed at the end of the call. Instead, you will be returned with 47 * a {@link ChannelFuture} instance which will notify you when the requested I/O 48 * operation has succeeded, failed, or canceled. 49 * 50 * <h3>Channels are hierarchical</h3> 51 * <p> 52 * A {@link Channel} can have a {@linkplain #getParent() parent} depending on 53 * how it was created. For instance, a {@link SocketChannel}, that was accepted 54 * by {@link ServerSocketChannel}, will return the {@link ServerSocketChannel} 55 * as its parent on {@link #getParent()}. 56 * <p> 57 * The semantics of the hierarchical structure depends on the transport 58 * implementation where the {@link Channel} belongs to. For example, you could 59 * write a new {@link Channel} implementation that creates the sub-channels that 60 * share one socket connection, as <a href="http://beepcore.org/">BEEP</a> and 61 * <a href="http://en.wikipedia.org/wiki/Secure_Shell">SSH</a> do. 62 * 63 * <h3>Downcast to access transport-specific operations</h3> 64 * <p> 65 * Some transports exposes additional operations that is specific to the 66 * transport. Down-cast the {@link Channel} to sub-type to invoke such 67 * operations. For example, with the old I/O datagram transport, multicast 68 * join / leave operations are provided by {@link DatagramChannel}. 69 * 70 * <h3>InterestOps</h3> 71 * <p> 72 * A {@link Channel} has a property called {@link #getInterestOps() interestOps} 73 * which is similar to that of {@link SelectionKey#interestOps() NIO SelectionKey}. 74 * It is represented as a <a href="http://en.wikipedia.org/wiki/Bit_field">bit 75 * field</a> which is composed of the two flags. 76 * <ul> 77 * <li>{@link #OP_READ} - If set, a message sent by a remote peer will be read 78 * immediately. If unset, the message from the remote peer will not be read 79 * until the {@link #OP_READ} flag is set again (i.e. read suspension).</li> 80 * <li>{@link #OP_WRITE} - If set, a write request will not be sent to a remote 81 * peer until the {@link #OP_WRITE} flag is cleared and the write request 82 * will be pending in a queue. If unset, the write request will be flushed 83 * out as soon as possible from the queue.</li> 84 * <li>{@link #OP_READ_WRITE} - This is a combination of {@link #OP_READ} and 85 * {@link #OP_WRITE}, which means only write requests are suspended.</li> 86 * <li>{@link #OP_NONE} - This is a combination of (NOT {@link #OP_READ}) and 87 * (NOT {@link #OP_WRITE}), which means only read operation is suspended.</li> 88 * </ul> 89 * </p><p> 90 * You can set or clear the {@link #OP_READ} flag to suspend and resume read 91 * operation via {@link #setReadable(boolean)}. 92 * </p><p> 93 * Please note that you cannot suspend or resume write operation just like you 94 * can set or clear {@link #OP_READ}. The {@link #OP_WRITE} flag is read only 95 * and provided simply as a mean to tell you if the size of pending write 96 * requests exceeded a certain threshold or not so that you don't issue too many 97 * pending writes that lead to an {@link OutOfMemoryError}. For example, the 98 * NIO socket transport uses the {@code writeBufferLowWaterMark} and 99 * {@code writeBufferHighWaterMark} properties in {@link NioSocketChannelConfig} 100 * to determine when to set or clear the {@link #OP_WRITE} flag. 101 * </p> 102 * 103 * @apiviz.landmark 104 * @apiviz.composedOf org.jboss.netty.channel.ChannelConfig 105 * @apiviz.composedOf org.jboss.netty.channel.ChannelPipeline 106 * 107 * @apiviz.exclude ^org\.jboss\.netty\.channel\.([a-z]+\.)+[^\.]+Channel$ 108 */ 109 public interface Channel extends Comparable<Channel> { 110 111 /** 112 * The {@link #getInterestOps() interestOps} value which tells that only 113 * read operation has been suspended. 114 */ 115 int OP_NONE = 0; 116 117 /** 118 * The {@link #getInterestOps() interestOps} value which tells that neither 119 * read nor write operation has been suspended. 120 */ 121 int OP_READ = 1; 122 123 /** 124 * The {@link #getInterestOps() interestOps} value which tells that both 125 * read and write operation has been suspended. 126 */ 127 int OP_WRITE = 4; 128 129 /** 130 * The {@link #getInterestOps() interestOps} value which tells that only 131 * write operation has been suspended. 132 */ 133 int OP_READ_WRITE = OP_READ | OP_WRITE; 134 135 /** 136 * Returns the unique integer ID of this channel. 137 */ 138 Integer getId(); 139 140 /** 141 * Returns the {@link ChannelFactory} which created this channel. 142 */ 143 ChannelFactory getFactory(); 144 145 /** 146 * Returns the parent of this channel. 147 * 148 * @return the parent channel. 149 * {@code null} if this channel does not have a parent channel. 150 */ 151 Channel getParent(); 152 153 /** 154 * Returns the configuration of this channel. 155 */ 156 ChannelConfig getConfig(); 157 158 /** 159 * Returns the {@link ChannelPipeline} which handles {@link ChannelEvent}s 160 * associated with this channel. 161 */ 162 ChannelPipeline getPipeline(); 163 164 /** 165 * Returns {@code true} if and only if this channel is open. 166 */ 167 boolean isOpen(); 168 169 /** 170 * Returns {@code true} if and only if this channel is bound to a 171 * {@linkplain #getLocalAddress() local address}. 172 */ 173 boolean isBound(); 174 175 /** 176 * Returns {@code true} if and only if this channel is connected to a 177 * {@linkplain #getRemoteAddress() remote address}. 178 */ 179 boolean isConnected(); 180 181 /** 182 * Returns the local address where this channel is bound to. The returned 183 * {@link SocketAddress} is supposed to be down-cast into more concrete 184 * type such as {@link InetSocketAddress} to retrieve the detailed 185 * information. 186 * 187 * @return the local address of this channel. 188 * {@code null} if this channel is not bound. 189 */ 190 SocketAddress getLocalAddress(); 191 192 /** 193 * Returns the remote address where this channel is connected to. The 194 * returned {@link SocketAddress} is supposed to be down-cast into more 195 * concrete type such as {@link InetSocketAddress} to retrieve the detailed 196 * information. 197 * 198 * @return the remote address of this channel. 199 * {@code null} if this channel is not connected. 200 * If this channel is not connected but it can receive messages 201 * from arbitrary remote addresses (e.g. {@link DatagramChannel}, 202 * use {@link MessageEvent#getRemoteAddress()} to determine 203 * the origination of the received message as this method will 204 * return {@code null}. 205 */ 206 SocketAddress getRemoteAddress(); 207 208 /** 209 * Sends a message to this channel asynchronously. If this channel was 210 * created by a connectionless transport (e.g. {@link DatagramChannel}) 211 * and is not connected yet, you have to call {@link #write(Object, SocketAddress)} 212 * instead. Otherwise, the write request will fail with 213 * {@link NotYetConnectedException} and an {@code 'exceptionCaught'} event 214 * will be triggered. 215 * 216 * @param message the message to write 217 * 218 * @return the {@link ChannelFuture} which will be notified when the 219 * write request succeeds or fails 220 * 221 * @throws NullPointerException if the specified message is {@code null} 222 */ 223 ChannelFuture write(Object message); 224 225 /** 226 * Sends a message to this channel asynchronously. It has an additional 227 * parameter that allows a user to specify where to send the specified 228 * message instead of this channel's current remote address. If this 229 * channel was created by a connectionless transport (e.g. {@link DatagramChannel}) 230 * and is not connected yet, you must specify non-null address. Otherwise, 231 * the write request will fail with {@link NotYetConnectedException} and 232 * an {@code 'exceptionCaught'} event will be triggered. 233 * 234 * @param message the message to write 235 * @param remoteAddress where to send the specified message. 236 * This method is identical to {@link #write(Object)} 237 * if {@code null} is specified here. 238 * 239 * @return the {@link ChannelFuture} which will be notified when the 240 * write request succeeds or fails 241 * 242 * @throws NullPointerException if the specified message is {@code null} 243 */ 244 ChannelFuture write(Object message, SocketAddress remoteAddress); 245 246 /** 247 * Binds this channel to the specified local address asynchronously. 248 * 249 * @param localAddress where to bind 250 * 251 * @return the {@link ChannelFuture} which will be notified when the 252 * bind request succeeds or fails 253 * 254 * @throws NullPointerException if the specified address is {@code null} 255 */ 256 ChannelFuture bind(SocketAddress localAddress); 257 258 /** 259 * Connects this channel to the specified remote address asynchronously. 260 * 261 * @param remoteAddress where to connect 262 * 263 * @return the {@link ChannelFuture} which will be notified when the 264 * connection request succeeds or fails 265 * 266 * @throws NullPointerException if the specified address is {@code null} 267 */ 268 ChannelFuture connect(SocketAddress remoteAddress); 269 270 /** 271 * Disconnects this channel from the current remote address asynchronously. 272 * 273 * @return the {@link ChannelFuture} which will be notified when the 274 * disconnection request succeeds or fails 275 */ 276 ChannelFuture disconnect(); 277 278 /** 279 * Unbinds this channel from the current local address asynchronously. 280 * 281 * @return the {@link ChannelFuture} which will be notified when the 282 * unbind request succeeds or fails 283 */ 284 ChannelFuture unbind(); 285 286 /** 287 * Closes this channel asynchronously. If this channel is bound or 288 * connected, it will be disconnected and unbound first. Once a channel 289 * is closed, it can not be open again. Calling this method on a closed 290 * channel has no effect. Please note that this method always returns the 291 * same future instance. 292 * 293 * @return the {@link ChannelFuture} which will be notified when the 294 * close request succeeds or fails 295 */ 296 ChannelFuture close(); 297 298 /** 299 * Returns the {@link ChannelFuture} which will be notified when this 300 * channel is closed. This method always returns the same future instance. 301 */ 302 ChannelFuture getCloseFuture(); 303 304 /** 305 * Returns the current {@code interestOps} of this channel. 306 * 307 * @return {@link #OP_NONE}, {@link #OP_READ}, {@link #OP_WRITE}, or 308 * {@link #OP_READ_WRITE} 309 */ 310 int getInterestOps(); 311 312 /** 313 * Returns {@code true} if and only if the I/O thread will read a message 314 * from this channel. This method is a shortcut to the following code: 315 * <pre> 316 * return (getInterestOps() & OP_READ) != 0; 317 * </pre> 318 */ 319 boolean isReadable(); 320 321 /** 322 * Returns {@code true} if and only if the I/O thread will perform the 323 * requested write operation immediately. Any write requests made when 324 * this method returns {@code false} are queued until the I/O thread is 325 * ready to process the queued write requests. This method is a shortcut 326 * to the following code: 327 * <pre> 328 * return (getInterestOps() & OP_WRITE) == 0; 329 * </pre> 330 */ 331 boolean isWritable(); 332 333 /** 334 * Changes the {@code interestOps} of this channel asynchronously. 335 * 336 * @param interestOps the new {@code interestOps} 337 * 338 * @return the {@link ChannelFuture} which will be notified when the 339 * {@code interestOps} change request succeeds or fails 340 */ 341 ChannelFuture setInterestOps(int interestOps); 342 343 /** 344 * Suspends or resumes the read operation of the I/O thread asynchronously. 345 * This method is a shortcut to the following code: 346 * <pre> 347 * int interestOps = getInterestOps(); 348 * if (readable) { 349 * setInterestOps(interestOps | OP_READ); 350 * } else { 351 * setInterestOps(interestOps & ~OP_READ); 352 * } 353 * </pre> 354 * 355 * @param readable {@code true} to resume the read operation and 356 * {@code false} to suspend the read operation 357 * 358 * @return the {@link ChannelFuture} which will be notified when the 359 * {@code interestOps} change request succeeds or fails 360 */ 361 ChannelFuture setReadable(boolean readable); 362 363 /** 364 * Retrieves an object which is {@link #setAttachment(Object) attached} to 365 * this {@link Channel}. 366 * 367 * @return {@code null} if no object was attached or {@code null} was 368 * attached 369 */ 370 Object getAttachment(); 371 372 /** 373 * Attaches an object to this {@link Channel} to store a stateful 374 * information 375 */ 376 void setAttachment(Object attachment); 377 }