View Javadoc

    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.socket.oio;
    17
    18  import static org.jboss.netty.channel.Channels.*;
    19
    20  import java.io.IOException;
    21  import java.net.InetAddress;
    22  import java.net.InetSocketAddress;
    23  import java.net.MulticastSocket;
    24  import java.net.NetworkInterface;
    25  import java.net.SocketException;
    26
    27  import org.jboss.netty.channel.ChannelException;
    28  import org.jboss.netty.channel.ChannelFactory;
    29  import org.jboss.netty.channel.ChannelFuture;
    30  import org.jboss.netty.channel.ChannelPipeline;
    31  import org.jboss.netty.channel.ChannelSink;
    32  import org.jboss.netty.channel.Channels;
    33  import org.jboss.netty.channel.socket.DatagramChannel;
    34  import org.jboss.netty.channel.socket.DatagramChannelConfig;
    35  import org.jboss.netty.channel.socket.DefaultDatagramChannelConfig;
    36
    37  final class OioDatagramChannel extends AbstractOioChannel
    38                                  implements DatagramChannel {
    39
    40      final MulticastSocket socket;
    41      private final DatagramChannelConfig config;
    42
    43      OioDatagramChannel(
    44              ChannelFactory factory,
    45              ChannelPipeline pipeline,
    46              ChannelSink sink) {
    47
    48          super(null, factory, pipeline, sink);
    49
    50          try {
    51              socket = new MulticastSocket(null);
    52          } catch (IOException e) {
    53              throw new ChannelException("Failed to open a datagram socket.", e);
    54          }
    55
    56          try {
    57              socket.setSoTimeout(10);
    58              socket.setBroadcast(false);
    59          } catch (SocketException e) {
    60              throw new ChannelException(
    61                      "Failed to configure the datagram socket timeout.", e);
    62          }
    63          config = new DefaultDatagramChannelConfig(socket);
    64
    65          fireChannelOpen(this);
    66
    67      }
    68
    69      public DatagramChannelConfig getConfig() {
    70          return config;
    71      }
    72
    73      public ChannelFuture joinGroup(InetAddress multicastAddress) {
    74          ensureBound();
    75          try {
    76              socket.joinGroup(multicastAddress);
    77              return Channels.succeededFuture(this);
    78          } catch (IOException e) {
    79              return Channels.failedFuture(this, e);
    80          }
    81      }
    82
    83      public ChannelFuture joinGroup(
    84              InetSocketAddress multicastAddress, NetworkInterface networkInterface) {
    85          ensureBound();
    86          try {
    87              socket.joinGroup(multicastAddress, networkInterface);
    88              return Channels.succeededFuture(this);
    89          } catch (IOException e) {
    90              return Channels.failedFuture(this, e);
    91          }
    92      }
    93
    94      private void ensureBound() {
    95          if (!isBound()) {
    96              throw new IllegalStateException(
    97                      DatagramChannel.class.getName() +
    98                      " must be bound to join a group.");
    99          }
    100     }
    101
    102     public ChannelFuture leaveGroup(InetAddress multicastAddress) {
    103         try {
    104             socket.leaveGroup(multicastAddress);
    105             return Channels.succeededFuture(this);
    106         } catch (IOException e) {
    107             return Channels.failedFuture(this, e);
    108         }
    109     }
    110
    111     public ChannelFuture leaveGroup(
    112             InetSocketAddress multicastAddress, NetworkInterface networkInterface) {
    113         try {
    114             socket.leaveGroup(multicastAddress, networkInterface);
    115             return Channels.succeededFuture(this);
    116         } catch (IOException e) {
    117             return Channels.failedFuture(this, e);
    118         }
    119     }
    120
    121     @Override
    122     boolean isSocketBound() {
    123         return socket.isBound();
    124     }
    125
    126     @Override
    127     boolean isSocketConnected() {
    128         return socket.isConnected();
    129     }
    130
    131     @Override
    132     InetSocketAddress getLocalSocketAddress() throws Exception {
    133         return (InetSocketAddress) socket.getLocalSocketAddress();
    134     }
    135
    136     @Override
    137     InetSocketAddress getRemoteSocketAddress() throws Exception {
    138         return (InetSocketAddress) socket.getRemoteSocketAddress();
    139     }
    140
    141     @Override
    142     void closeSocket() throws IOException {
    143         socket.close();
    144     }
    145
    146     @Override
    147     boolean isSocketClosed() {
    148         return socket.isClosed();
    149     }
    150
    151
    152 }