/****************************************************************************
* Copyright (c) 2004 Composent, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Composent, Inc. - initial API and implementation
*****************************************************************************/
package org.eclipse.ecf.provider.comm.tcp;
import java.io.IOException;
import java.net.*;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ecf.core.util.Trace;
import org.eclipse.ecf.internal.provider.ECFProviderDebugOptions;
import org.eclipse.ecf.internal.provider.ProviderPlugin;
public class Server extends ServerSocket {
public static final int DEFAULT_BACKLOG = 50;
ISocketAcceptHandler acceptHandler;
Thread listenerThread;
ThreadGroup threadGroup;
protected void debug(String msg) {
Trace.trace(ProviderPlugin.PLUGIN_ID, ECFProviderDebugOptions.CONNECTION, msg);
}
protected void traceStack(String msg, Throwable e) {
Trace.catching(ProviderPlugin.PLUGIN_ID, ECFProviderDebugOptions.EXCEPTIONS_CATCHING, Server.class, msg, e);
}
/**
* @param group thread group for created threads
* @param port port
* @param backlog backlog
* @param bindAddress a bindAddress
* @param handler the socket accept handler
* @throws IOException if server setup cannot be done
* @since 4.4
*/
public Server(ThreadGroup group, int port, int backlog, InetAddress bindAddress, ISocketAcceptHandler handler) throws IOException {
super(port, backlog, bindAddress);
if (handler == null)
throw new NullPointerException("Socket accept handler cannot be null"); //$NON-NLS-1$
acceptHandler = handler;
threadGroup = group;
listenerThread = setupListener();
listenerThread.start();
}
/**
* @param group thread group for created threads
* @param port port
* @param bindAddress a bindAddress
* @param handler the socket accept handler
* @throws IOException if server setup cannot be done
* @since 4.4
*/
public Server(ThreadGroup group, int port, InetAddress bindAddress, ISocketAcceptHandler handler) throws IOException {
this(group, port, DEFAULT_BACKLOG, bindAddress, handler);
}
/**
* @param group thread group for created threads
* @param port port
* @param backlog backlog
* @param handler the socket accept handler
* @throws IOException if server setup cannot be done
* @since 4.4
*/
public Server(ThreadGroup group, int port, int backlog, ISocketAcceptHandler handler) throws IOException {
this(null, port, backlog, null, handler);
}
public Server(ThreadGroup group, int port, ISocketAcceptHandler handler) throws IOException {
this(group, port, DEFAULT_BACKLOG, handler);
}
public Server(int port, ISocketAcceptHandler handler) throws IOException {
this(null, port, handler);
}
protected Thread setupListener() {
return new Thread(threadGroup, new Runnable() {
public void run() {
while (true) {
try {
handleAccept(accept());
} catch (Exception e) {
traceStack("Exception in accept", e); //$NON-NLS-1$
// If we get an exception on accept(), we should just
// exit
break;
}
}
debug("Closing listener normally."); //$NON-NLS-1$
}
}, "ServerApplication(" + getLocalPort() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
}
protected void handleAccept(final Socket aSocket) {
new Thread(threadGroup, new Runnable() {
public void run() {
try {
debug("accept:" + aSocket.getInetAddress()); //$NON-NLS-1$
acceptHandler.handleAccept(aSocket);
} catch (Exception e) {
traceStack("Unexpected exception in handleAccept...closing", //$NON-NLS-1$
e);
try {
aSocket.close();
} catch (IOException e1) {
ProviderPlugin.getDefault().log(new Status(IStatus.ERROR, ProviderPlugin.PLUGIN_ID, IStatus.ERROR, "accept.close", e1)); //$NON-NLS-1$
}
}
}
}).start();
}
public synchronized void close() throws IOException {
super.close();
if (listenerThread != null) {
listenerThread.interrupt();
listenerThread = null;
}
if (threadGroup != null) {
threadGroup.interrupt();
threadGroup = null;
}
acceptHandler = null;
}
}