1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.transport.nio;
21
22 import java.io.IOException;
23 import java.net.SocketAddress;
24 import java.net.SocketException;
25 import java.nio.channels.DatagramChannel;
26
27 import org.apache.mina.api.IdleStatus;
28 import org.apache.mina.api.IoFuture;
29 import org.apache.mina.api.IoSession;
30 import org.apache.mina.api.MinaRuntimeException;
31 import org.apache.mina.service.executor.IoHandlerExecutor;
32 import org.apache.mina.service.idlechecker.IndexedIdleChecker;
33 import org.apache.mina.transport.ConnectFuture;
34 import org.apache.mina.transport.udp.AbstractUdpClient;
35 import org.apache.mina.transport.udp.UdpSessionConfig;
36 import org.apache.mina.util.Assert;
37
38
39
40
41
42
43 public class NioUdpClient extends AbstractUdpClient {
44
45
46
47 private final SelectorLoopPool readWriteSelectorPool;
48
49 private final IndexedIdleChecker idleChecker = new IndexedIdleChecker();
50
51
52
53
54 public NioUdpClient() {
55 this(null);
56 }
57
58
59
60
61 public NioUdpClient(IoHandlerExecutor ioHandlerExecutor) {
62 super(ioHandlerExecutor);
63 readWriteSelectorPool = new FixedSelectorLoopPool("Client", 2);
64 idleChecker.start();
65 }
66
67
68
69
70 @Override
71 public IoFuture<IoSession> connect(SocketAddress remoteAddress) {
72 Assert.assertNotNull(remoteAddress, "remoteAddress");
73
74 DatagramChannel ch;
75 try {
76 ch = DatagramChannel.open();
77 } catch (IOException e) {
78 throw new MinaRuntimeException("can't create a new socket, out of file descriptors ?", e);
79 }
80 try {
81 ch.configureBlocking(false);
82 } catch (IOException e) {
83 throw new MinaRuntimeException("can't configure socket as non-blocking", e);
84 }
85
86 UdpSessionConfig config = getSessionConfig();
87
88 NioSelectorLoop loop = (NioSelectorLoop) readWriteSelectorPool.getSelectorLoop();
89
90 NioUdpSession session = new NioUdpSession(this, idleChecker, ch, null, remoteAddress, loop);
91
92 session.setConnected();
93
94
95 session.getConfig().setIdleTimeInMillis(IdleStatus.READ_IDLE, config.getIdleTimeInMillis(IdleStatus.READ_IDLE));
96 session.getConfig().setIdleTimeInMillis(IdleStatus.WRITE_IDLE,
97 config.getIdleTimeInMillis(IdleStatus.WRITE_IDLE));
98
99
100 idleChecker.sessionRead(session, System.currentTimeMillis());
101 idleChecker.sessionWritten(session, System.currentTimeMillis());
102
103
104
105 Boolean reuseAddress = config.isReuseAddress();
106
107 if (reuseAddress != null) {
108 session.getConfig().setReuseAddress(reuseAddress);
109 }
110
111 Integer readBufferSize = config.getReadBufferSize();
112
113 if (readBufferSize != null) {
114 session.getConfig().setReadBufferSize(readBufferSize);
115 } else {
116 int rcvBufferSize;
117 try {
118 rcvBufferSize = ch.socket().getReceiveBufferSize();
119 session.getConfig().setReadBufferSize(rcvBufferSize);
120
121 } catch (SocketException e) {
122 throw new MinaRuntimeException("can't configure socket receive buffer size", e);
123 }
124 }
125
126 Integer sendBufferSize = config.getSendBufferSize();
127
128 if (sendBufferSize != null) {
129 session.getConfig().setSendBufferSize(sendBufferSize);
130 } else {
131 int sndBufferSize;
132 try {
133 sndBufferSize = ch.socket().getSendBufferSize();
134 session.getConfig().setSendBufferSize(sndBufferSize);
135 } catch (SocketException e) {
136 throw new MinaRuntimeException("can't configure socket send buffe size", e);
137 }
138 }
139
140 Integer trafficClass = config.getTrafficClass();
141
142 if (trafficClass != null) {
143 session.getConfig().setTrafficClass(trafficClass);
144 }
145
146 loop.register(false, false, true, false, session, ch, null);
147
148 ConnectFuture cf = new ConnectFuture();
149 cf.complete(session);
150
151 return cf;
152 }
153
154
155
156
157 @Override
158 public IoFuture<IoSession> connect(SocketAddress remoteAddress, SocketAddress localAddress) {
159 throw new IllegalStateException("not supported for UDP");
160 }
161 }