1 4 package com.tc.util; 5 6 import com.tc.net.EphemeralPorts; 7 import com.tc.net.EphemeralPorts.Range; 8 9 import java.io.IOException ; 10 import java.net.BindException ; 11 import java.net.ServerSocket ; 12 import java.util.HashSet ; 13 import java.util.Random ; 14 import java.util.Set ; 15 16 public final class PortChooser { 17 private static final Object VM_WIDE_LOCK = (PortChooser.class.getName() + "LOCK").intern(); 18 private static final Set chosen = new HashSet (); 19 private static final Random random = new Random (); 20 private static final Range exclude = EphemeralPorts.getRange(); 21 22 public int chooseRandomPort() { 23 synchronized (VM_WIDE_LOCK) { 24 return choose(); 25 } 26 } 27 28 private int choose() { 29 while (true) { 30 final Integer attempt = new Integer (getNonEphemeralPort()); 31 boolean added = chosen.add(attempt); 32 if (!added) { 33 continue; } 35 36 ServerSocket ss = null; 37 try { 38 int port = attempt.intValue(); 39 ss = new ServerSocket (port); 40 return port; 41 } catch (BindException be) { 42 continue; } catch (IOException e) { 44 throw new RuntimeException (e); 45 } finally { 46 if (ss != null) { 47 while (!ss.isClosed()) { 48 try { 49 ss.close(); 50 } catch (IOException e) { 51 } 53 } 54 } 55 } 56 } 57 } 58 59 private static int getNonEphemeralPort() { 60 while (true) { 61 int p = random.nextInt(65535 - 1024) + 1024; 62 if (p < exclude.getLower() || p > exclude.getUpper()) { return p; } 63 } 64 } 65 66 } 67 | Popular Tags |