2
* JBoss, Home of Professional Open Source
3
* Copyright 2005, JBoss Inc., and individual contributors as indicated
4
* by the @authors tag. See the copyright.txt in the distribution for a
5
* full listing of individual contributors.
7
* This is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU Lesser General Public License as
9
* published by the Free Software Foundation; either version 2.1 of
10
* the License, or (at your option) any later version.
12
* This software is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this software; if not, write to the Free
19
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
24
* Created on Jul 24, 2005
27
package org.jboss.remoting.transport.multiplex;
29
import org.jboss.logging.Logger;
31
import javax.net.ServerSocketFactory;
32
import java.io.IOException;
33
import java.io.Serializable;
34
import java.net.InetAddress;
35
import java.net.InetSocketAddress;
36
import java.net.ServerSocket;
37
import java.net.Socket;
38
import java.net.SocketAddress;
39
import java.net.SocketException;
40
import java.net.SocketTimeoutException;
41
import java.nio.channels.ServerSocketChannel;
42
import java.util.HashMap;
47
* <code>MasterServerSocket</code> is one of the two implementations of a server socket in the
48
* Multiplex project. For each socket created in the <code>accept()</code> method, it builds
49
* a virtual socket group. For more details, see the Multiplex documentation on
50
* the labs.jboss.org web site.
53
* Most of the methods in <code>MasterServerSocket</code> override those in its parent class,
54
* <code>java.net.ServerSocket</code>. For method descriptions, see the <code>ServerSocket</code> javadoc.
59
* @author <a href="mailto:r.sigal@computer.org">Ron Sigal</a>
61
* @deprecated As of release 2.4.0 the multiplex transport will no longer be actively supported.
63
public class MasterServerSocket extends ServerSocket implements Serializable
65
private static final Logger log = Logger.getLogger(MasterServerSocket.class);
66
private Map configuration = new HashMap();
67
private ServerSocket ss;
68
private ServerSocketChannel ssc;
69
private static final long serialVersionUID = 402293949935889044L;
72
* @throws java.io.IOException
74
public MasterServerSocket() throws IOException
81
* @throws java.io.IOException
83
public MasterServerSocket(int port) throws IOException
91
* @throws java.io.IOException
93
public MasterServerSocket(int port, int backlog) throws IOException
95
this(true, port, backlog);
102
* @throws java.io.IOException
104
public MasterServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException
106
this(true, port, backlog, bindAddr);
110
* @throws java.io.IOException
112
public MasterServerSocket(boolean nio) throws IOException
116
ssc = ServerSocketChannel.open();
121
ss = new ServerSocket();
127
* @throws java.io.IOException
129
public MasterServerSocket(boolean nio, int port) throws IOException
133
ssc = ServerSocketChannel.open();
135
ss.bind(new InetSocketAddress(port));
139
ss = new ServerSocket(port);
146
* @throws java.io.IOException
148
public MasterServerSocket(boolean nio, int port, int backlog) throws IOException
152
ssc = ServerSocketChannel.open();
154
ss.bind(new InetSocketAddress(port), backlog);
158
ss = new ServerSocket(port, backlog);
166
* @throws java.io.IOException
168
public MasterServerSocket(boolean nio, int port, int backlog, InetAddress bindAddr) throws IOException
172
ssc = ServerSocketChannel.open();
174
ss.bind(new InetSocketAddress(bindAddr, port), backlog);
178
ss = new ServerSocket(port, backlog, bindAddr);
185
* Create a new <code>MasterServerSocket</code>.
186
* If <code>Map</code> conf contains key <code>Multiplex.SERVER_SOCKET_FACTORY</code>, will use it.
187
* Otherwise, will create an NIO <code>ServerSocket</code>.
193
* @throws IOException
195
public MasterServerSocket(int port, int backlog, InetAddress bindAddr, Map conf) throws IOException
198
configuration.putAll((conf));
200
if (conf == null || conf.get(Multiplex.SERVER_SOCKET_FACTORY) == null)
202
ssc = ServerSocketChannel.open();
204
ss.bind(new InetSocketAddress(bindAddr, port), backlog);
208
Object obj = conf.get(Multiplex.SERVER_SOCKET_FACTORY);
209
if (!(obj instanceof ServerSocketFactory))
211
String msg = "configuration map contains invalid entry for Multiplex.SERVER_SOCKET_FACTORY: " + obj;
213
throw new IOException(msg);
215
ServerSocketFactory ssf = (ServerSocketFactory) obj;
216
ss = ssf.createServerSocket(port, backlog, bindAddr);
223
* @throws IOException
225
public MasterServerSocket(ServerSocketFactory ssf) throws IOException
227
ss = ssf.createServerSocket();
234
* @throws IOException
236
public MasterServerSocket(ServerSocketFactory ssf, int port) throws IOException
238
ss = ssf.createServerSocket(port);
246
* @throws IOException
248
public MasterServerSocket(ServerSocketFactory ssf, int port, int backlog) throws IOException
250
ss = ssf.createServerSocket(port, backlog);
259
* @throws IOException
261
public MasterServerSocket(ServerSocketFactory ssf, int port, int backlog, InetAddress bindAddr)
264
ss = ssf.createServerSocket(port, backlog, bindAddr);
268
//////////////////////////////////////////////////////////////////////////////////////////////////
269
/// The following methods are required of any ServerSocket '///
270
//////////////////////////////////////////////////////////////////////////////////////////////////
274
ok: public Socket accept() throws IOException;
275
ok: public void bind(SocketAddress endpoint) throws IOException;
276
ok: public void bind(SocketAddress endpoint, int backlog) throws IOException;
277
ok: public void close() throws IOException;
278
ok: public ServerSocketChannel getChannel();
279
ok: public InetAddress getInetAddress();
280
ok: public int getLocalPort();
281
ok: public SocketAddress getLocalSocketAddress();
282
ok: public int getReceiveBufferSize() throws SocketException;
283
ok: public boolean getReuseAddress() throws SocketException;
284
ok: public int getSoTimeout() throws IOException;
285
ok: public boolean isBound();
286
ok: public boolean isClosed();
287
ok: public void setReceiveBufferSize(int size) throws SocketException;
288
ok: public void setReuseAddress(boolean on) throws SocketException;
289
ok: public void setSoTimeout(int timeout) throws SocketException;
290
ok: public String toString();
295
* See <code>java.net.ServerSocket</code> javadoc.
297
public Socket accept() throws IOException
299
long start = System.currentTimeMillis();
300
int timeout = getSoTimeout();
301
int savedTimeout = timeout;
303
Socket socket = null;
304
SocketTimeoutException savedException = null;
309
if ((timeLeft = timeout - (int) (System.currentTimeMillis() - start)) <= 0)
310
throw new SocketTimeoutException("Accept timed out");
312
setSoTimeout(timeLeft);
316
socket = ss.accept();
318
catch (SocketTimeoutException e)
320
// NIO ServerSocket doesn't set message.
321
savedException = new SocketTimeoutException("Accept timed out");
322
throw savedException;
328
setSoTimeout(savedTimeout);
330
catch (Exception e) {}
332
if (savedException != null)
333
throw savedException;
336
MultiplexingManager manager = MultiplexingManager.getaManager(socket, configuration);
337
MultiplexingInputStream is = null;
338
Protocol protocol = null;
339
SocketId clientPort = null;
343
is = manager.getAnInputStream(SocketId.SERVER_SOCKET_ID, null);
344
protocol = manager.getProtocol();
347
if ((timeLeft = timeout - (int) (System.currentTimeMillis() - start)) <= 0)
348
throw new SocketTimeoutException("Accept timed out");
350
clientPort = protocol.acceptConnect(is, timeLeft);
352
catch (SocketTimeoutException e)
354
log.debug("i/o exception in MasterServerSocket.accept()");
355
manager.decrementReferences();
358
catch (IOException e)
360
log.error("i/o exception in MasterServerSocket.accept()", e);
361
manager.decrementReferences();
365
if (log.isDebugEnabled())
366
log.debug("accept(): clientPort: " + clientPort.getPort());
368
// connection from independent VirtualServerSocket
369
if (clientPort.getPort() < 0)
371
MultiplexingOutputStream os = new MultiplexingOutputStream(manager, SocketId.SERVER_SOCKET_CONNECT_ID);
375
protocol.answerConnect(os, SocketId.SERVER_SOCKET_CONNECT_PORT);
377
catch (IOException e)
379
// If this connect timed out at the other end, there may not be an OutputStream to write to.
380
log.error("unable to respond to connect request");
381
manager.decrementReferences();
383
if (e instanceof SocketTimeoutException)
384
throw new SocketTimeoutException("Accept timed out");
389
// Keept trying to accept a request for a VirtualSocket connection.
393
VirtualSocket virtualSocket = null;
397
virtualSocket = new VirtualSocket(manager, clientPort, configuration);
399
catch (IOException e)
401
manager.decrementReferences();
405
int localPort = virtualSocket.getLocalVirtualPort();
409
protocol.answerConnect((MultiplexingOutputStream)virtualSocket.getOutputStream(), localPort);
411
catch (IOException e)
413
// If this connect timed out at the other end, there may not be an OutputStream to write to.
414
log.error("unable to respond to connect request");
415
virtualSocket.close();
419
return virtualSocket;
425
* See <code>java.net.ServerSocket</code> javadoc.
427
public void bind(SocketAddress endpoint) throws IOException
434
* See <code>java.net.ServerSocket</code> javadoc.
436
public void bind(SocketAddress endpoint, int backlog) throws IOException
438
ss.bind(endpoint, backlog);
443
* See <code>java.net.ServerSocket</code> javadoc.
445
public void close() throws IOException
447
log.debug("MasterServerSocket: closing");
452
* See <code>java.net.ServerSocket</code> javadoc.
454
public ServerSocketChannel getChannel()
456
return ss.getChannel();
461
* See <code>java.net.ServerSocket</code> javadoc.
463
public InetAddress getInetAddress()
465
return ss.getInetAddress();
470
* See <code>java.net.ServerSocket</code> javadoc.
472
public int getLocalPort()
474
return ss.getLocalPort();
479
* See <code>java.net.ServerSocket</code> javadoc.
481
public SocketAddress getLocalSocketAddress()
483
return ss.getLocalSocketAddress();
488
* See <code>java.net.ServerSocket</code> javadoc.
490
public int getReceiveBufferSize() throws SocketException
492
return ss.getReceiveBufferSize();
497
* See <code>java.net.ServerSocket</code> javadoc.
499
public boolean getReuseAddress() throws SocketException
501
return ss.getReuseAddress();
506
* See <code>java.net.ServerSocket</code> javadoc.
508
public int getSoTimeout() throws IOException
510
return ss.getSoTimeout();
515
* See <code>java.net.ServerSocket</code> javadoc.
517
public boolean isBound()
524
* See <code>java.net.ServerSocket</code> javadoc.
526
public boolean isClosed()
528
return ss.isClosed();
533
* See <code>java.net.ServerSocket</code> javadoc.
535
public void setReceiveBufferSize(int size) throws SocketException
537
ss.setReceiveBufferSize(size);
542
* See <code>java.net.ServerSocket</code> javadoc.
544
public void setReuseAddress(boolean on) throws SocketException
546
ss.setReuseAddress(on);
551
* See <code>java.net.ServerSocket</code> javadoc.
553
public void setSoTimeout(int timeout) throws SocketException
555
ss.setSoTimeout(timeout);
560
* See <code>java.net.ServerSocket</code> javadoc.
562
public String toString()
565
return "MasterServerSocket[unbound]";
567
return "MasterServerSocket[" + ss.toString() + "]";
571
//////////////////////////////////////////////////////////////////////////////////////////////////
572
// / The following methods are specific to MasterServerSocket '///
573
//////////////////////////////////////////////////////////////////////////////////////////////////
576
* Accepts a connection from a remote <code>VirtualServerSocket</code>.
578
public int acceptServerSocketConnection() throws IOException
580
long start = System.currentTimeMillis();
581
int timeout = getSoTimeout();
582
int savedTimeout = timeout;
585
// Socket socket = ss.accept();
586
Socket socket = null;
589
socket = ss.accept();
591
socket = ssc.accept().socket();
593
MultiplexingManager manager = MultiplexingManager.getaManager(socket, configuration);
594
manager.setCreatedForRemoteServerSocket();
595
MultiplexingInputStream is = null;
596
Protocol protocol = null;
597
SocketId clientPort = null;
601
is = manager.getAnInputStream(SocketId.SERVER_SOCKET_ID, null);
602
protocol = manager.getProtocol();
605
if ((timeLeft = timeout - (int) (System.currentTimeMillis() - start)) <= 0)
606
throw new SocketTimeoutException("Accept timed out");
608
clientPort = protocol.acceptConnect(is, timeLeft);
610
catch (IOException e)
612
log.error("i/o exception in MasterServerSocket.acceptServerSocketConnection()", e);
613
manager.decrementReferences();
615
if (e instanceof SocketTimeoutException)
616
throw new SocketTimeoutException("Accept timed out");
621
if (clientPort.getPort() != SocketId.SERVER_SOCKET_PORT)
623
manager.decrementReferences();
624
String message = "received connect request not from a VirtualServerSocket";
626
throw new IOException(message);
629
MultiplexingOutputStream os = new MultiplexingOutputStream(manager, SocketId.SERVER_SOCKET_CONNECT_ID);
633
protocol.answerConnect(os, SocketId.SERVER_SOCKET_CONNECT_PORT);
635
catch (IOException e)
637
// If this connect timed out at the other end, there may not be an OutputStream to write to.
638
log.error("unable to respond to connect request");
639
manager.decrementReferences();
643
return manager.getSocket().getLocalPort();
647
public void setConfiguration(Map configuration)
649
this.configuration.putAll(configuration);
b'\\ No newline at end of file'