/******************************************************************************* * Copyright (c) 2003, 2011 IBM Corporation 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: * IBM Corporation - Initial API and implementation *******************************************************************************/ package org.eclipse.wst.internet.monitor.core.internal; import java.io.InterruptedIOException; import java.net.*; import org.eclipse.wst.internet.monitor.core.internal.provisional.IMonitor; /** * The actual TCP/IP monitoring server. This is a thread that * listens on a port and relays a call to another server. */ public class AcceptThread { protected IMonitor monitor; protected boolean alive = true; protected ServerSocket serverSocket; protected Thread thread; class ServerThread extends Thread { public ServerThread() { super("TCP/IP Monitor"); } /** * ServerThread accepts incoming connections and delegates to the protocol * adapter to deal with the connection. */ public void run() { // create a new server socket try { serverSocket = new ServerSocket(monitor.getLocalPort()); serverSocket.setSoTimeout(2000); if (Trace.FINEST) { Trace.trace(Trace.STRING_FINEST, "Monitoring localhost:" + monitor.getLocalPort() + " -> " + monitor.getRemoteHost() + ":" + monitor.getRemotePort()); } } catch (Exception e) { if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, "Could not start monitoring"); } return; } while (alive) { try { // accept the connection from the client Socket localSocket = serverSocket.accept(); int timeout = monitor.getTimeout(); if (timeout != 0) localSocket.setSoTimeout(timeout); try { // connect to the remote server Socket remoteSocket = new Socket(); if (timeout != 0) remoteSocket.setSoTimeout(timeout); remoteSocket.connect(new InetSocketAddress(monitor.getRemoteHost(), monitor.getRemotePort()), timeout); // relay the call through String protocolId = monitor.getProtocol(); ProtocolAdapter adapter = MonitorPlugin.getInstance().getProtocolAdapter(protocolId); adapter.connect(monitor, localSocket, remoteSocket); } catch (SocketTimeoutException e) { FailedConnectionThread thread2 = new FailedConnectionThread((Monitor) monitor, localSocket, Messages.errorConnectTimeout); thread2.start(); } catch (Exception e) { FailedConnectionThread thread2 = new FailedConnectionThread((Monitor) monitor, localSocket, null); thread2.start(); } } catch (InterruptedIOException e) { // do nothing } catch (Exception e) { if (alive) if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, "Error while monitoring", e); } } } } } /** * AcceptThread constructor. * * @param monitor a monitor */ public AcceptThread(IMonitor monitor) { super(); this.monitor = monitor; } /** * Start the server. */ public void startServer() { if (thread != null) return; thread = new ServerThread(); thread.setDaemon(true); thread.setPriority(Thread.NORM_PRIORITY + 1); thread.start(); Thread.yield(); // wait up to 2 seconds for initialization int i = 0; while (serverSocket == null && i < 10) { try { Thread.sleep(200); } catch (Exception e) { // ignore } i++; } } /** * Returns <code>true</code> if the server is running. * * @return <code>true</code> if the server is running, and <code>false</code> * otherwise */ public boolean isRunning() { return (thread != null); } /** * Correctly close the server socket and shut down the server. */ public void stopServer() { try { alive = false; thread = null; String protocolId = monitor.getProtocol(); ProtocolAdapter adapter = MonitorPlugin.getInstance().getProtocolAdapter(protocolId); adapter.disconnect(monitor); if (serverSocket != null) serverSocket.close(); } catch (Exception e) { if (Trace.SEVERE) { Trace.trace(Trace.STRING_SEVERE, "Error stopping server", e); } } } /** * Returns true if this port is in use. * * @return boolean * @param port int */ public static boolean isPortInUse(int port) { ServerSocket s = null; try { s = new ServerSocket(port); } catch (SocketException e) { return true; } catch (Exception e) { return true; } finally { if (s != null) { try { s.close(); } catch (Exception e) { // ignore } } } return false; } }