001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.jmeter.protocol.http.control;
020:
021: import java.io.InterruptedIOException;
022: import java.net.ServerSocket;
023: import java.net.Socket;
024:
025: import org.apache.jorphan.logging.LoggingManager;
026: import org.apache.jorphan.util.JOrphanUtils;
027: import org.apache.log.Logger;
028:
029: /**
030: * Server daemon thread.
031: * Creates main socket and listens on it.
032: * For each client request, creates a thread to handle the request.
033: *
034: */
035: public class HttpMirrorServer extends Thread {
036: private static final Logger log = LoggingManager
037: .getLoggerForClass();
038:
039: /**
040: * The time (in milliseconds) to wait when accepting a client connection.
041: * The accept will be retried until the Daemon is told to stop. So this
042: * interval is the longest time that the Daemon will have to wait after
043: * being told to stop.
044: */
045: private static final int ACCEPT_TIMEOUT = 1000;
046:
047: /** The port to listen on. */
048: private final int daemonPort;
049:
050: /** True if the Daemon is currently running. */
051: private volatile boolean running;
052:
053: /**
054: * Create a new Daemon with the specified port and target.
055: *
056: * @param port
057: * the port to listen on.
058: */
059: public HttpMirrorServer(int port) {
060: super ("HttpMirrorServer");
061: this .daemonPort = port;
062: }
063:
064: /**
065: * Listen on the daemon port and handle incoming requests. This method will
066: * not exit until {@link #stopServer()} is called or an error occurs.
067: */
068: public void run() {
069: running = true;
070: ServerSocket mainSocket = null;
071:
072: try {
073: log.info("Creating HttpMirror ... on port " + daemonPort);
074: mainSocket = new ServerSocket(daemonPort);
075: mainSocket.setSoTimeout(ACCEPT_TIMEOUT);
076: log.info("HttpMirror up and running!");
077:
078: while (running) {
079: try {
080: // Listen on main socket
081: Socket clientSocket = mainSocket.accept();
082: if (running) {
083: // Pass request to new thread
084: HttpMirrorThread thd = new HttpMirrorThread(
085: clientSocket);
086: log.info("Starting new Mirror thread");
087: thd.start();
088: } else {
089: log.warn("Server not running");
090: JOrphanUtils.closeQuietly(clientSocket);
091: }
092: } catch (InterruptedIOException e) {
093: // Timeout occurred. Ignore, and keep looping until we're
094: // told to stop running.
095: }
096: }
097: log.info("HttpMirror Server stopped");
098: } catch (Exception e) {
099: log.warn("HttpMirror Server stopped", e);
100: } finally {
101: JOrphanUtils.closeQuietly(mainSocket);
102: }
103: }
104:
105: public void stopServer() {
106: running = false;
107: }
108: }
|