Home | History | Annotate | Download | only in support
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package tests.support;
     19 
     20 import java.net.DatagramSocket;
     21 import java.net.ServerSocket;
     22 import java.util.Calendar;
     23 import java.util.TimeZone;
     24 
     25 /**
     26  * The port manager is supposed to help finding a free
     27  * network port on the machine; however, it uses strange
     28  * logic, so leave it to the OS.
     29  *
     30  * @deprecated Use OS to find free ports.
     31  */
     32 public class Support_PortManager {
     33 
     34     private static int lastAssignedPort = somewhatRandomPort();
     35     private static boolean failedOnce = false;
     36 
     37     public static synchronized int getNextPort() {
     38         if (!failedOnce) {
     39             try {
     40                 ServerSocket ss = new ServerSocket(0);
     41                 int port = ss.getLocalPort();
     42 
     43                 ss.close();
     44                 return port;
     45             } catch (Exception ex) {
     46                 failedOnce = true;
     47             }
     48         }
     49         return getNextPort_unsafe();
     50     }
     51 
     52     /**
     53      * Returns 1 free ports to be used.
     54      */
     55     public static synchronized int getNextPortForUDP() {
     56         return getNextPortsForUDP(1)[0];
     57     }
     58 
     59     /**
     60      * Returns the specified number of free ports to be used.
     61      */
     62     public static synchronized int[] getNextPortsForUDP(int num) {
     63         if (num <= 0) {
     64             throw new IllegalArgumentException("Invalid ports number: " + num);
     65         }
     66         DatagramSocket[] dss = new DatagramSocket[num];
     67         int[] ports = new int[num];
     68 
     69         try {
     70             for (int i = 0; i < num; ++i) {
     71                 dss[i] = new DatagramSocket(0);
     72                 ports[i] = dss[i].getLocalPort();
     73             }
     74         } catch (Exception ex) {
     75             throw new Error("Unable to get " + num + " ports for UDP: " + ex);
     76         } finally {
     77             for (int i = 0; i < num; ++i) {
     78                 if (dss[i] != null) {
     79                     dss[i].close();
     80                 }
     81             }
     82         }
     83         return ports;
     84     }
     85 
     86     public static synchronized int getNextPort_unsafe() {
     87         if (++lastAssignedPort > 65534) {
     88             lastAssignedPort = 6000;
     89         }
     90         return lastAssignedPort;
     91     }
     92 
     93     /*
     94       * Returns a different port number every 6 seconds or so. The port number
     95       * should be about += 100 at each 6 second interval
     96       */
     97     private static int somewhatRandomPort() {
     98         Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
     99         int minutes = c.get(Calendar.MINUTE);
    100         int seconds = c.get(Calendar.SECOND);
    101 
    102         return 6000 + (1000 * minutes) + ((seconds / 6) * 100);
    103     }
    104 
    105 }
    106