001package net.gdface.thrift; 002import java.net.InetAddress; 003import java.net.NetworkInterface; 004import java.net.SocketException; 005import java.net.UnknownHostException; 006import java.util.Iterator; 007import java.util.List; 008import java.util.Set; 009 010import static com.google.common.base.Preconditions.checkNotNull; 011 012import com.google.common.collect.ImmutableSet; 013import com.google.common.collect.Iterators; 014 015import com.google.common.base.Predicates; 016 017import com.google.common.base.Joiner; 018 019import com.google.common.base.Predicate; 020import com.google.common.collect.Lists; 021import com.google.common.primitives.Bytes; 022 023import com.google.common.base.Function; 024 025/** 026 * 网络管ç†å·¥å…·ç±» 027 * @author guyadong 028 * @deprecated instead use {@link net.gdface.utils.NetworkUtil} in com.gitee.l0km:common-base2 since version 1.0.7 029 */ 030public class NetworkUtil { 031 public static final String DEFAULT_HOST = "localhost"; 032 public static enum Radix{ 033 /** 二进制 */BIN(2), 034 /** å进制 */DEC(10), 035 /** åå…进制 */HEX(16); 036 final int value; 037 Radix(int radix){ 038 this.value = radix; 039 } 040 } 041 public static enum Filter implements Predicate<NetworkInterface>{ 042 /** 过滤器: æ‰€æœ‰ç½‘å¡ */ALL, 043 /** 过滤器: 在线设备,see also {@link NetworkInterface#isUp()} */UP, 044 /** 过滤器: 虚拟接å£,see also {@link NetworkInterface#isVirtual()} */VIRTUAL, 045 /** 过滤器:LOOPBACK, see also {@link NetworkInterface#isLoopback()} */LOOPBACK, 046 /** 过滤器:物ç†ç½‘å¡ */PHYICAL_ONLY; 047 048 @Override 049 public boolean apply(NetworkInterface input) { 050 if(null == input ){ 051 return false; 052 } 053 try{ 054 switch(this){ 055 case UP: 056 return input.isUp(); 057 case VIRTUAL: 058 return input.isVirtual(); 059 case LOOPBACK: 060 return input.isLoopback(); 061 case PHYICAL_ONLY :{ 062 byte[] hardwareAddress = input.getHardwareAddress(); 063 return null != hardwareAddress 064 && hardwareAddress.length > 0 065 && !input.isVirtual() 066 && !isVMMac(hardwareAddress); 067 } 068 case ALL: 069 default : 070 return true; 071 } 072 } catch (SocketException e) { 073 throw new RuntimeException(e); 074 } 075 } 076 } 077 /** 078 * æ ¹æ®è¿‡æ»¤å™¨{@code filters}指定的æ¡ä»¶(AND)返回网å¡è®¾å¤‡å¯¹è±¡ 079 * @param filters 080 * @return 081 */ 082 @SafeVarargs 083 @SuppressWarnings("unchecked") 084 public static Set<NetworkInterface> getNICs(Predicate<NetworkInterface> ...filters) { 085 if(null == filters){ 086 filters = new Predicate[]{Filter.ALL}; 087 } 088 try { 089 Iterator<NetworkInterface> filtered = Iterators.filter( 090 Iterators.forEnumeration(NetworkInterface.getNetworkInterfaces()), 091 Predicates.and(filters)); 092 return ImmutableSet.copyOf(filtered); 093 } catch (SocketException e) { 094 throw new RuntimeException(e); 095 } 096 } 097 /** 098 * 返回所有物ç†ç½‘å¡ 099 * @return 100 */ 101 public static Set<NetworkInterface> getPhysicalNICs() { 102 return getNICs(Filter.PHYICAL_ONLY,Filter.UP); 103 } 104 /** 105 * å°†{@code byte[]} 转æ¢ä¸º{@code radix}æŒ‡å®šæ ¼å¼çš„å—符串 106 * 107 * @param source 108 * @param separator 分隔符 109 * @param radix 进制基数 110 * @return {@code source}为{@code null}时返回空å—符串 111 */ 112 public static final String format(byte[] source,String separator, final Radix radix) { 113 if (null == source){ 114 return ""; 115 } 116 if(null == separator){ 117 separator = ""; 118 } 119 List<String> hex = Lists.transform(Bytes.asList(source),new Function<Byte,String>(){ 120 @Override 121 public String apply(Byte input) { 122 return String.copyValueOf(new char[]{ 123 Character.forDigit((input & 240) >> 4, radix.value), 124 Character.forDigit(input & 15, radix.value) 125 }); 126 }}); 127 return Joiner.on(separator).join(hex); 128 } 129 /** 130 * MACåœ°å€æ ¼å¼(16进制)æ ¼å¼åŒ–{@code source}指定的å—节数组 131 * @see #format(byte[], String, Radix) 132 */ 133 public static final String formatMac(byte[] source,String separator) { 134 return format(source,separator,Radix.HEX); 135 } 136 /** 137 * 以IPåœ°å€æ ¼å¼(点分ä½)æ ¼å¼åŒ–{@code source}指定的å—节数组<br> 138 * @see #format(byte[], String, Radix) 139 */ 140 public static final String formatIp(byte[] source) { 141 return format(source,".",Radix.DEC); 142 } 143 /** 144 * 返回指定{@code address}绑定的网å¡çš„物ç†åœ°å€(MAC) 145 * @param address 146 * @return 指定的{@code address}没有绑定在任何网å¡ä¸Šè¿”回{@code null} 147 * @see NetworkInterface#getByInetAddress(InetAddress) 148 * @see NetworkInterface#getHardwareAddress() 149 */ 150 public static byte[] getMacAddress(InetAddress address) { 151 try { 152 NetworkInterface nic = NetworkInterface.getByInetAddress(address); 153 return null == nic ? null : nic.getHardwareAddress(); 154 } catch (SocketException e) { 155 throw new RuntimeException(e); 156 } 157 } 158 /** 159 * @param nic 网å¡å¯¹è±¡ 160 * @param separator æ ¼å¼åŒ–分隔符 161 * @return 表示MAC地å€çš„å—符串 162 */ 163 public static String getMacAddress(NetworkInterface nic,String separator) { 164 try { 165 return format(nic.getHardwareAddress(),separator, Radix.HEX); 166 } catch (SocketException e) { 167 throw new RuntimeException(e); 168 } 169 } 170 /** 171 * å‚è§ {@link #getMacAddress(InetAddress)} 172 * @param address 173 * @param separator æ ¼å¼åŒ–分隔符 174 * @return 表示MAC地å€çš„å—符串 175 */ 176 public static String getMacAddress(InetAddress address,String separator) { 177 return format(getMacAddress(address),separator, Radix.HEX); 178 } 179 private static byte invalidMacs[][] = { 180 /** VMWare */{0x00, 0x05, 0x69}, 181 /** VMWare */{0x00, 0x1C, 0x14}, 182 /** VMWare */{0x00, 0x0C, 0x29}, 183 /** VMWare */{0x00, 0x50, 0x56}, 184 /** Virtualbox */{0x08, 0x00, 0x27}, 185 /** Virtualbox */{0x0A, 0x00, 0x27}, 186 /** Virtual-PC */{0x00, 0x03, (byte)0xFF}, 187 /** Hyper-V */{0x00, 0x15, 0x5D} 188 }; 189 private static boolean isVMMac(byte[] mac) { 190 if(null == mac) { 191 return false; 192 } 193 194 for (byte[] invalid: invalidMacs){ 195 if (invalid[0] == mac[0] && invalid[1] == mac[1] && invalid[2] == mac[2]) { 196 return true; 197 } 198 } 199 return false; 200 } 201 /** 判æ–{@code host}是å¦ä¸ºlocalhost */ 202 public static final boolean isLoopbackAddress(String host) { 203 return "127.0.0.1".equals(host) 204 || "::1".equals(host) 205 || DEFAULT_HOST.equals(host); 206 } 207 /** 判æ–{@code address}是å¦ä¸ºæœ¬æœºåœ°å€ */ 208 public static final boolean isLocalhost(InetAddress address) { 209 try { 210 return address.isLoopbackAddress() 211 || InetAddress.getLocalHost().getHostAddress().equals( address.getHostAddress()) ; 212 } catch (UnknownHostException e) { 213 throw new RuntimeException(e); 214 } 215 } 216 /** 判æ–{@code address}是å¦ä¸ºæœ¬æœºåœ°å€ */ 217 public static final boolean isLocalhost(String host) { 218 try { 219 return isLoopbackAddress(host) || isLocalhost(InetAddress.getByName(checkNotNull(host))); 220 } catch (UnknownHostException e) { 221 return false; 222 } 223 } 224 /** 如果{@code host}为localhost转æ¢ä¸º{@value #DEFAULT_HOST} */ 225 public static final String convertHost(String host) { 226 return isLoopbackAddress(host)? DEFAULT_HOST : host; 227 } 228 229 /** é历所有物ç†ç½‘上绑定的地å€,判æ–{@code address}是å¦ä¸ºæœ¬æœºç½‘å¡ç»‘å®šçš„åœ°å€ */ 230 public static boolean selfBind(final InetAddress address){ 231 if(isLocalhost(address)){ 232 return true; 233 } 234 final Predicate<InetAddress> filter = new Predicate<InetAddress>(){ 235 @Override 236 public boolean apply(InetAddress input) { 237 return input.getHostAddress().equals(address.getHostAddress()); 238 }}; 239 return Iterators.tryFind(getPhysicalNICs().iterator(),new Predicate<NetworkInterface>(){ 240 @Override 241 public boolean apply(NetworkInterface input) { 242 return Iterators.tryFind( 243 Iterators.forEnumeration(input.getInetAddresses()), 244 filter).isPresent(); 245 }}).isPresent(); 246 } 247 /** see also {@link #selfBind(InetAddress)} */ 248 public static boolean selfBind(String host){ 249 try { 250 return selfBind(InetAddress.getByName(host)); 251 } catch (UnknownHostException e) { 252 return false; 253 } 254 } 255}