package org.jdiameter.server.impl.io.tcp; import org.jdiameter.client.api.parser.IMessageParser; import org.jdiameter.client.impl.transport.tcp.TCPClientConnection; import org.jdiameter.server.api.io.INetWorkConnectionListener; import org.jdiameter.server.api.io.INetWorkGuard; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; public class NetWorkGuard implements INetWorkGuard, Runnable { protected IMessageParser parser; protected int port; protected Logger logger = LoggerFactory.getLogger(NetWorkGuard.class); protected CopyOnWriteArrayList<INetWorkConnectionListener> listeners = new CopyOnWriteArrayList<INetWorkConnectionListener>(); protected boolean isWork = false; protected Selector selector; protected ServerSocket serverSocket; private Thread thread = new Thread(this); public NetWorkGuard(InetAddress inetAddress, int port, IMessageParser parser) throws Exception { this.port = port; this.parser = parser; // try { ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.configureBlocking(false); serverSocket = ssc.socket(); serverSocket.bind( new InetSocketAddress( inetAddress, port ) ); selector = Selector.open(); ssc.register(selector, SelectionKey.OP_ACCEPT); isWork = true; logger.info("Open server socket {} ", serverSocket); thread.start(); } catch(Exception exc) { destroy(); throw new Exception(exc); } } public void run() { try { while (isWork) { int num = selector.select(); if (num == 0) continue; Set keys = selector.selectedKeys(); for (Object key1 : keys) { SelectionKey key = (SelectionKey) key1; if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { try { Socket s = serverSocket.accept(); logger.info("Open incomming connection {}", s); TCPClientConnection client = new TCPClientConnection(null, s, parser, null); for (INetWorkConnectionListener listener : listeners) { listener.newNetWorkConnection(client); } } catch (Exception e) { logger.warn("Can not create incoming connection", e); } } } keys.clear(); } } catch(Exception exc) { logger.warn("Server socket stopped", exc); } } public void addListener(INetWorkConnectionListener listener) { if (!listeners.contains(listener)) { listeners.add(listener); } } public void remListener(INetWorkConnectionListener listener) { listeners.remove(listener); } @Override public String toString() { return "NetworkGuard:" + (serverSocket != null ? serverSocket.toString() : "closed"); } public void destroy() { try { isWork = false; try { if (thread != null) { thread.join(1000); if (thread.isAlive()) thread.interrupt(); } } catch (InterruptedException e) { logger.debug("Can not stop thread", e ); } if (serverSocket != null) { serverSocket.close(); } thread = null; serverSocket = null; } catch (IOException e) { logger.info(e.getMessage()); } } }