package org.greencheek.dns.lookup; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; /** * Created by dominictootell on 29/03/2014. */ public class TCPAddressChecker implements AddressChecker { private final long connectionTimeoutInMillis; public TCPAddressChecker(long connectionTimeoutInMillis) { this.connectionTimeoutInMillis = connectionTimeoutInMillis; } @Override public boolean isAvailable(InetSocketAddress address) { SocketChannel ch = null; Selector selector = null; boolean connectedOk = false; boolean hasException = false; try { // Create selector selector = Selector.open(); ch = SocketChannel.open(); ch.configureBlocking(false); ch.connect(address); // Register connection event to selector (OP_CONNECT type) ch.register(selector, SelectionKey.OP_CONNECT); // Waiting for the connection while (selector.select(connectionTimeoutInMillis) > 0) { // Get keys Set keys = selector.selectedKeys(); Iterator i = keys.iterator(); // For each key... while (i.hasNext()) { SelectionKey key = (SelectionKey)i.next(); // Remove the current key i.remove(); // Attempt a connection if (key.isConnectable()) { // Get the socket channel held by the key SocketChannel channel = (SocketChannel)key.channel(); // Close pendent connections if(channel.finishConnect()) { // Remove the interrest in the connect // as you are connected key.interestOps(key.interestOps() ^ SelectionKey.OP_CONNECT); } } connectedOk = true; } break; } } catch (Exception e) { hasException = true; } finally { if(selector!=null) { try { selector.close(); } catch (Exception e) { } } if (ch != null) { try { Socket s = ch.socket(); if (s != null) { try { s.setSoLinger(false, 0); s.close(); } catch (IOException e) { } } ch.close(); } catch (IOException e) { } } if(connectedOk && !hasException) { return true; } else { return false; } } } }