Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Licensed to the Apache Software Foundation (ASF) under one or more
0003  * contributor license agreements.  See the NOTICE file distributed with
0004  * this work for additional information regarding copyright ownership.
0005  * The ASF licenses this file to You under the Apache License, Version 2.0
0006  * (the "License"); you may not use this file except in compliance with
0007  * the License.  You may obtain a copy of the License at
0008  *
0009  *    http://www.apache.org/licenses/LICENSE-2.0
0010  *
0011  * Unless required by applicable law or agreed to in writing, software
0012  * distributed under the License is distributed on an "AS IS" BASIS,
0013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014  * See the License for the specific language governing permissions and
0015  * limitations under the License.
0016  */
0017 
0018 package org.apache.hadoop.net;
0019 
0020 import org.slf4j.Logger;
0021 import org.slf4j.LoggerFactory;
0022 
0023 import java.io.IOException;
0024 import java.net.ServerSocket;
0025 import java.util.Random;
0026 
0027 /**
0028  * Copied from
0029  * hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/net/ServerSocketUtil.java
0030  * for Hadoop-3.x testing
0031  */
0032 public class ServerSocketUtil {
0033 
0034   private static final Logger LOG = LoggerFactory.getLogger(ServerSocketUtil.class);
0035   private static Random rand = new Random();
0036 
0037   /**
0038    * Port scan & allocate is how most other apps find ports
0039    *
0040    * @param port given port
0041    * @param retries number of retries
0042    * @return
0043    * @throws IOException
0044    */
0045   public static int getPort(int port, int retries) throws IOException {
0046     int tryPort = port;
0047     int tries = 0;
0048     while (true) {
0049       if (tries > 0 || tryPort == 0) {
0050         tryPort = port + rand.nextInt(65535 - port);
0051       }
0052       if (tryPort == 0) {
0053         continue;
0054       }
0055       try (ServerSocket s = new ServerSocket(tryPort)) {
0056         LOG.info("Using port " + tryPort);
0057         return tryPort;
0058       } catch (IOException e) {
0059         tries++;
0060         if (tries >= retries) {
0061           LOG.info("Port is already in use; giving up");
0062           throw e;
0063         } else {
0064           LOG.info("Port is already in use; trying again");
0065         }
0066       }
0067     }
0068   }
0069 
0070   /**
0071    * Check whether port is available or not.
0072    *
0073    * @param port given port
0074    * @return
0075    */
0076   private static boolean isPortAvailable(int port) {
0077     try (ServerSocket s = new ServerSocket(port)) {
0078       return true;
0079     } catch (IOException e) {
0080       return false;
0081     }
0082   }
0083 
0084   /**
0085    * Wait till the port available.
0086    *
0087    * @param port given port
0088    * @param retries number of retries for given port
0089    * @return
0090    * @throws InterruptedException
0091    * @throws IOException
0092    */
0093   public static int waitForPort(int port, int retries)
0094           throws InterruptedException, IOException {
0095     int tries = 0;
0096     while (true) {
0097       if (isPortAvailable(port)) {
0098         return port;
0099       } else {
0100         tries++;
0101         if (tries >= retries) {
0102           throw new IOException(
0103                   "Port is already in use; giving up after " + tries + " times.");
0104         }
0105         Thread.sleep(1000);
0106       }
0107     }
0108   }
0109 
0110   /**
0111    * Find the specified number of unique ports available.
0112    * The ports are all closed afterwards,
0113    * so other network services started may grab those same ports.
0114    *
0115    * @param numPorts number of required port nubmers
0116    * @return array of available port numbers
0117    * @throws IOException
0118    */
0119   public static int[] getPorts(int numPorts) throws IOException {
0120     ServerSocket[] sockets = new ServerSocket[numPorts];
0121     int[] ports = new int[numPorts];
0122     for (int i = 0; i < numPorts; i++) {
0123       ServerSocket sock = new ServerSocket(0);
0124       sockets[i] = sock;
0125       ports[i] = sock.getLocalPort();
0126     }
0127     for (ServerSocket sock : sockets) {
0128       sock.close();
0129     }
0130     return ports;
0131   }
0132 }