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