1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 }