fix local port bug

This commit is contained in:
Looly 2020-03-08 17:41:57 +08:00
parent 3c1060769e
commit fb4af337ea
4 changed files with 122 additions and 125 deletions

View File

@ -10,6 +10,7 @@
### Bug修复
* 【setting】 修复Props.toBean方法null的问题
* 【core 】 修复DataUtil.parseLocalDateTime无时间部分报错问题issue#I1B18H@Gitee
* 【core 】 修复NetUtil.isUsableLocalPort()判断问题issue#765@Github
-------------------------------------------------------------------------------------------------------------

View File

@ -1,13 +1,25 @@
package cn.hutool.core.net;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import java.io.IOException;
import java.io.OutputStream;
import java.net.DatagramSocket;
import java.net.IDN;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.URL;
@ -21,31 +33,22 @@ import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
import javax.net.ServerSocketFactory;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
/**
* 网络相关工具
*
* @author xiaoleilu
*
*/
public class NetUtil {
public final static String LOCAL_IP = "127.0.0.1";
/** 默认最小端口1024 */
/**
* 默认最小端口1024
*/
public static final int PORT_RANGE_MIN = 1024;
/** 默认最大端口65535 */
/**
* 默认最大端口65535
*/
public static final int PORT_RANGE_MAX = 0xFFFF;
/**
@ -103,12 +106,21 @@ public class NetUtil {
// 给定的IP未在指定端口范围中
return false;
}
try {
ServerSocketFactory.getDefault().createServerSocket(port, 1, InetAddress.getByName(LOCAL_IP)).close();
return true;
} catch (Exception e) {
// issue#765@Github, 某些绑定非127.0.0.1的端口无法被检测到
try (ServerSocket ss = new ServerSocket(port)) {
ss.setReuseAddress(true);
} catch (IOException ignored) {
return false;
}
try (DatagramSocket ds = new DatagramSocket(port)) {
ds.setReuseAddress(true);
} catch (IOException ignored) {
return false;
}
return true;
}
/**
@ -159,7 +171,7 @@ public class NetUtil {
* @since 4.5.4
*/
public static int getUsableLocalPort(int minPort, int maxPort) {
final int maxPortExclude = maxPort +1;
final int maxPortExclude = maxPort + 1;
int randomPort;
for (int i = minPort; i < maxPortExclude; i++) {
randomPort = RandomUtil.randomInt(minPort, maxPortExclude);
@ -314,9 +326,9 @@ public class NetUtil {
}
NetworkInterface netInterface;
while(networkInterfaces.hasMoreElements()){
while (networkInterfaces.hasMoreElements()) {
netInterface = networkInterfaces.nextElement();
if(null != netInterface && name.equals(netInterface.getName())){
if (null != netInterface && name.equals(netInterface.getName())) {
return netInterface;
}
}
@ -432,7 +444,7 @@ public class NetUtil {
* 获取本机网卡IP地址这个地址为所有网卡中非回路地址的第一个<br>
* 如果获取失败调用 {@link InetAddress#getLocalHost()}方法获取<br>
* 此方法不会抛出异常获取失败将返回<code>null</code><br>
*
* <p>
* 参考http://stackoverflow.com/questions/9481865/getting-the-ip-address-of-the-current-machine-using-java
*
* @return 本机网卡IP地址获取失败返回<code>null</code>
@ -453,9 +465,9 @@ public class NetUtil {
* 1. 查找所有网卡地址必须非回路loopback地址非局域网地址siteLocalIPv4地址
* 2. 如果无满足要求的地址调用 {@link InetAddress#getLocalHost()} 获取地址
* </pre>
*
* <p>
* 此方法不会抛出异常获取失败将返回<code>null</code><br>
*
* <p>
* https://github.com/looly/hutool/issues/428
*
* @return 本机网卡IP地址获取失败返回<code>null</code>
@ -553,7 +565,6 @@ public class NetUtil {
}
/**
*
* 简易的使用Socket发送数据
*
* @param host Server主机
@ -573,7 +584,6 @@ public class NetUtil {
}
/**
*
* 使用普通Socket发送数据
*
* @param host Server主机
@ -684,6 +694,7 @@ public class NetUtil {
}
// ----------------------------------------------------------------------------------------- Private method start
/**
* 指定IP的long是否在指定范围内
*

View File

@ -379,35 +379,17 @@ public class RandomUtil {
*
* @param length 长度
* @return 随机索引
* @since 5.2.1
*/
public static int[] createRandomList(int length){
int[] list = ArrayUtil.range(length);
public static int[] randomInts(int length){
final int[] range = ArrayUtil.range(length);
for (int i = 0; i < length; i++) {
int random = randomInt(i,length);
ArrayUtil.swap(list,i,random);
ArrayUtil.swap(range,i,random);
}
return list;
return range;
}
/**
* 随机获得列表中的一定量的元素返回List
*
* @param source 列表
* @param count 随机取出的个数
* @param <T> 元素类型
* @return 随机列表
*/
public static <T> List<T> randomEleList(List<T> source, int count){
if(count >= source.size()){
return source;
}
int[] randomList = ArrayUtil.sub(createRandomList(source.size()),0,count);
List<T> result = new ArrayList<>();
for (int e: randomList){
result.add(source.get(e));
}
return result;
}
/**
* 获得一个随机的字符串只包含数字和字符
*

View File

@ -1,14 +1,12 @@
package cn.hutool.core.net;
import java.net.InetAddress;
import cn.hutool.core.lang.PatternPool;
import cn.hutool.core.util.ReUtil;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import cn.hutool.core.lang.PatternPool;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.ReUtil;
import java.net.InetAddress;
/**
* NetUtil单元测试
@ -54,4 +52,9 @@ public class NetUtilTest {
long ipLong = NetUtil.ipv4ToLong("127.0.0.1");
Assert.assertEquals(2130706433L, ipLong);
}
@Test
public void isUsableLocalPortTest(){
Assert.assertTrue(NetUtil.isUsableLocalPort(80));
}
}