You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iec61850bean/src/main/java/org/openmuc/jositransport/ServerThread.java

150 lines
4.6 KiB
Java

/*
* Copyright 2011-17 Fraunhofer ISE, energy & meteo Systems GmbH and other contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.openmuc.jositransport;
import org.openmuc.openiec61850.internal.NamedDefaultThreadFactory;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* This class extends Thread. It is started by ServerTSAP and listens on a socket for connections and hands them to the
* ConnectionHandler class. It notifies ConnectionListener if the socket is closed.
*
* @author Stefan Feuerhahn
*
*/
final class ServerThread extends Thread {
private final ServerSocket serverSocket;
private final int maxTPduSizeParam;
private final int messageTimeout;
private final int messageFragmentTimeout;
private final int maxConnections;
private final TConnectionListener connectionListener;
private boolean stopServer = false;
private int numConnections = 0;
ServerThread(ServerSocket socket, int maxTPduSizeParam, int maxConnections, int messageTimeout,
int messageFragmentTimeout, TConnectionListener connectionListener) {
serverSocket = socket;
this.maxTPduSizeParam = maxTPduSizeParam;
this.maxConnections = maxConnections;
this.messageTimeout = messageTimeout;
this.messageFragmentTimeout = messageFragmentTimeout;
this.connectionListener = connectionListener;
}
public final class ConnectionHandler extends Thread {
private final Socket socket;
private final ServerThread serverThread;
ConnectionHandler(Socket socket, ServerThread serverThread) {
this.socket = socket;
this.serverThread = serverThread;
}
@Override
public void run() {
TConnection tConnection;
try {
tConnection = new TConnection(socket, maxTPduSizeParam, messageTimeout, messageFragmentTimeout,
serverThread);
} catch (IOException e) {
synchronized (ServerThread.this) {
numConnections--;
}
return;
}
try {
tConnection.listenForCR();
} catch (IOException e) {
tConnection.close();
return;
}
connectionListener.connectionIndication(tConnection);
}
}
@Override
public void run() {
ExecutorService executor = Executors.newCachedThreadPool(new NamedDefaultThreadFactory("openiec61850-osi-server"));
try {
Socket clientSocket = null;
while (true) {
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
if (stopServer == false) {
connectionListener.serverStoppedListeningIndication(e);
}
return;
}
boolean startConnection = false;
synchronized (this) {
if (numConnections < maxConnections) {
numConnections++;
startConnection = true;
}
}
if (startConnection) {
executor.execute(new ConnectionHandler(clientSocket, this));
}
else {
// Maximum number of connections reached. Ignoring connection request.
}
}
} finally {
executor.shutdown();
}
}
void connectionClosedSignal() {
synchronized (this) {
numConnections--;
}
}
/**
* Stops listening for new connections. Existing connections are not touched.
*/
void stopServer() {
stopServer = true;
if (serverSocket.isBound()) {
try {
serverSocket.close();
} catch (IOException e) {
}
}
}
}