1 /**********************************************************************
2 * ConnectionAcceptor.java
3 * created on 01.03.2005 by netseeker
4 * $Source: /cvsroot/ejoe/EJOE/src/de/netseeker/ejoe/ConnectionAcceptor.java,v $
5 * $Date: 2006/03/22 00:06:58 $
6 * $Revision: 1.24 $
7 *
8 * ====================================================================
9 *
10 * Copyright 2005-2006 netseeker aka Michael Manske
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 * ====================================================================
24 *
25 * This file is part of the ejoe framework.
26 * For more information on the author, please see
27 * <http://www.manskes.de/>.
28 *
29 *********************************************************************/
30 package de.netseeker.ejoe;
31
32 import java.io.IOException;
33 import java.nio.channels.CancelledKeyException;
34 import java.nio.channels.SelectionKey;
35 import java.nio.channels.Selector;
36 import java.nio.channels.ServerSocketChannel;
37 import java.nio.channels.SocketChannel;
38 import java.nio.channels.spi.SelectorProvider;
39 import java.util.Iterator;
40 import java.util.logging.Level;
41 import java.util.logging.Logger;
42
43 import de.netseeker.ejoe.io.IOUtils;
44
45 /***
46 * The ConnectionAcceptor class is a server thread handling accepting of incoming client connections and simply hands
47 * over these connections to another thread for further processing. The adavantage of the separation of acception
48 * management and processing management *can* result in a significantly higher throughput if dealing with a lot of
49 * clients.
50 *
51 * @author netseeker
52 * @since 0.3.0
53 */
54 final class ConnectionAcceptor extends Thread
55 {
56 private static final Logger logger = Logger.getLogger(ConnectionAcceptor.class.getName());
57
58 private ServerSocketChannel _channel;
59
60 private ChannelRegistrar _registrar;
61
62 private Selector _selector = null;
63
64 public ConnectionAcceptor(final ServerSocketChannel channel, final ChannelRegistrar registrar) throws IOException
65 {
66 this._channel = channel;
67 this._registrar = registrar;
68 this._selector = SelectorProvider.provider().openSelector();
69 }
70
71
72
73
74
75
76 public void run()
77 {
78 try
79 {
80 this._channel.register(_selector, SelectionKey.OP_ACCEPT);
81
82 while (!isInterrupted())
83 {
84 if (_selector.select() == 0)
85 {
86 continue;
87 }
88
89 Iterator it = _selector.selectedKeys().iterator();
90 SelectionKey selKey = null;
91 SocketChannel cChannel = null;
92 ConnectionHeader header = null;
93
94 while (it.hasNext())
95 {
96 selKey = (SelectionKey) it.next();
97 it.remove();
98
99 try
100 {
101
102 if (!selKey.isValid())
103 {
104 continue;
105 }
106
107 if (selKey.isAcceptable())
108 {
109 cChannel = this._channel.accept();
110
111 if (cChannel != null)
112 {
113 cChannel.socket().setTrafficClass(EJConstants.IPTOS_THROUGHPUT);
114 cChannel.socket().setReuseAddress(true);
115 cChannel.configureBlocking(false);
116
117
118 header = new ConnectionHeader(cChannel );
119 this._registrar.register(header, SelectionKey.OP_READ);
120 if (logger.isLoggable(Level.FINE))
121 {
122 logger.log(Level.FINE, "Connection accepted from "
123 + cChannel.socket().getRemoteSocketAddress());
124 }
125 }
126 }
127 }
128 catch (CancelledKeyException cke)
129 {
130 logger.log(Level.WARNING, "Key canceled!", cke);
131 }
132 }
133 }
134 }
135 catch (IOException e)
136 {
137 logger.log(Level.SEVERE, "!!! IOException occured !!! ", e);
138 throw new RuntimeException(e);
139 }
140 finally
141 {
142 try
143 {
144 IOUtils.closeQuite(_selector);
145 }
146 catch (Exception e)
147 {
148 logger.log(Level.SEVERE, "!!! Error while stopping server !!!", e);
149 }
150 }
151 }
152 }