package socket2_improved;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.Collections;

/**
 * Testet, welche Ports an einem Rechner verfuegbar sind. Um Zeit einzusparen wird
 * je Port der Test in einem Thread ausgelagert.
 * 
 * @author Ralf Kunze (rkunze@uos.de), Institut fuer Informatik, Universitaet
 *         Osnabrueck
 * @date 06.06.2007
 */
public class PortsAvailableTest {

    public static void main(String[] args) {

        // Map zum speichern der Ports/Sockets
        Map<Integer, Socket> map = new TreeMap<Integer, Socket>();
        // Die Map synchronisieren, da mehrere Threads gleichzeitig darauf zugreifen
        map = Collections.synchronizedMap(map);
        
        // Eine Liste fuer alle Threads
        List<SocketTestThread> l = new LinkedList<SocketTestThread>();

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String hostname = null;
        
        // Hostname einlesen
        try {
            System.out.print("Bitte geben sie einen Hostname ein: ");
            hostname = br.readLine();
        } catch (IOException e1) {
            System.err.println("Could not read from stdin. Bye!");
            System.exit(1);
        }
        
        long time = System.currentTimeMillis();
        
        // InetAddress erzeugen und fuer jeden zu testenden
        // Port einen Thread anlegen und starten
        try {
            InetAddress address = InetAddress.getByName(hostname);
            for (int i = 0; i < 100; i++) {
                SocketTestThread s = new SocketTestThread(address, i, map);
                l.add(s);
                s.start();
            }

            // auf die Threads warten
            for(SocketTestThread s: l) {
                s.join();
            }
            
            // Freie Ports ausgeben
            System.out.println("Available ports:");
            for(Integer i:map.keySet()) {
                System.out.println("\t" + i);
            }
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(System.currentTimeMillis()-time + "MS");

    }

}
