/** * 给定一个地点的不完全名字,得到一系列包含s子串的IP范围记录 * * @param s 地点子串 * @return 包含IPEntry类型的List */ public List getIPEntriesDebug(String s) { List<IPEntry> ret = new ArrayList<IPEntry>(); long endOffset = ipEnd + 4; for (long offset = ipBegin + 4; offset <= endOffset; offset += IP_RECORD_LENGTH) { // 读取结束IP偏移 long temp = readLong3(offset); // 如果temp不等于-1,读取IP的地点信息 if (temp != -1) { IPLocation ipLoc = getIPLocation(temp); // 判断是否这个地点里面包含了s子串,如果包含了,添加这个记录到List中,如果没有,继续 if (ipLoc.getCountry().indexOf(s) != -1 || ipLoc.getArea().indexOf(s) != -1) { IPEntry entry = new IPEntry(); entry.country = ipLoc.getCountry(); entry.area = ipLoc.getArea(); // 得到起始IP readIP(offset - 4, b4); entry.beginIp = Util.getIpStringFromBytes(b4); // 得到结束IP readIP(temp, b4); entry.endIp = Util.getIpStringFromBytes(b4); // 添加该记录 ret.add(entry); } } } return ret; }
/** * 根据ip搜索ip信息文件,得到IPLocation结构,所搜索的ip参数从类成员ip中得到 * * @param ip 要查询的IP * @return IPLocation结构 */ private IPLocation getIPLocation(byte[] ip) { IPLocation info = null; long offset = locateIP(ip); if (offset != -1) info = getIPLocation(offset); if (info == null) { info = new IPLocation(); info.setCountry(Message.unknown_country); info.setArea(Message.unknown_area); } return info; }
/** * 根据ip搜索ip信息文件,得到IPLocation结构,所搜索的ip参数从类成员ip中得到 * * @param ip 要查询的IP * @return IPLocation结构 */ private IPLocation getIPLocation(byte[] ip) { IPLocation info = null; long offset = locateIP(ip); if (offset != -1) info = getIPLocation(offset); if (info == null) { info = new IPLocation(); info.country = "未知"; info.area = "未知"; } return info; }
/** * 根据IP得到地区名 * * @param ip ip的字节数组形式 * @return 地区名字符串 */ public String getArea(byte[] ip) { // 检查ip地址文件是否正常 if (ipFile == null) return Message.bad_ip_file; // 保存ip,转换ip字节数组为字符串形式 String ipStr = Util.getIpStringFromBytes(ip); // 先检查cache中是否已经包含有这个ip的结果,没有再搜索文件 if (ipCache.containsKey(ipStr)) { IPLocation ipLoc = ipCache.get(ipStr); return ipLoc.getArea(); } else { IPLocation ipLoc = getIPLocation(ip); ipCache.put(ipStr, ipLoc.getCopy()); return ipLoc.getArea(); } }
/** * 给定一个ip国家地区记录的偏移,返回一个IPLocation结构,此方法应用与内存映射文件方式 * * @param offset 国家记录的起始偏移 * @return IPLocation对象 */ private IPLocation getIPLocation(int offset) { // 跳过4字节ip mbb.position(offset + 4); // 读取第一个字节判断是否标志字节 byte b = mbb.get(); if (b == REDIRECT_MODE_1) { // 读取国家偏移 int countryOffset = readInt3(); // 跳转至偏移处 mbb.position(countryOffset); // 再检查一次标志字节,因为这个时候这个地方仍然可能是个重定向 b = mbb.get(); if (b == REDIRECT_MODE_2) { loc.setCountry(readString(readInt3())); mbb.position(countryOffset + 4); } else loc.setCountry(readString(countryOffset)); // 读取地区标志 loc.setArea(readArea(mbb.position())); } else if (b == REDIRECT_MODE_2) { loc.setCountry(readString(readInt3())); loc.setArea(readArea(offset + 8)); } else { loc.setCountry(readString(mbb.position() - 1)); loc.setArea(readArea(mbb.position())); } return loc; }
/** * 给定一个ip国家地区记录的偏移,返回一个IPLocation结构 * * @param offset 国家记录的起始偏移 * @return IPLocation对象 */ private IPLocation getIPLocation(long offset) { try { // 跳过4字节ip ipFile.seek(offset + 4); // 读取第一个字节判断是否标志字节 byte b = ipFile.readByte(); if (b == REDIRECT_MODE_1) { // 读取国家偏移 long countryOffset = readLong3(); // 跳转至偏移处 ipFile.seek(countryOffset); // 再检查一次标志字节,因为这个时候这个地方仍然可能是个重定向 b = ipFile.readByte(); if (b == REDIRECT_MODE_2) { loc.setCountry(readString(readLong3())); ipFile.seek(countryOffset + 4); } else loc.setCountry(readString(countryOffset)); // 读取地区标志 loc.setArea(readArea(ipFile.getFilePointer())); } else if (b == REDIRECT_MODE_2) { loc.setCountry(readString(readLong3())); loc.setArea(readArea(offset + 8)); } else { loc.setCountry(readString(ipFile.getFilePointer() - 1)); loc.setArea(readArea(ipFile.getFilePointer())); } return loc; } catch (IOException e) { return null; } }
/** * 给定一个地点的不完全名字,得到一系列包含s子串的IP范围记录 * * @param s 地点子串 * @return 包含IPEntry类型的List */ public List<IPEntry> getIPEntries(String s) { List<IPEntry> ret = new ArrayList<IPEntry>(); try { // 映射IP信息文件到内存中 if (mbb == null) { FileChannel fc = ipFile.getChannel(); mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, ipFile.length()); mbb.order(ByteOrder.LITTLE_ENDIAN); } int endOffset = (int) ipEnd; for (int offset = (int) ipBegin + 4; offset <= endOffset; offset += IP_RECORD_LENGTH) { int temp = readInt3(offset); if (temp != -1) { IPLocation ipLoc = getIPLocation(temp); // 判断是否这个地点里面包含了s子串,如果包含了,添加这个记录到List中,如果没有,继续 if (ipLoc.getCountry().indexOf(s) != -1 || ipLoc.getArea().indexOf(s) != -1) { IPEntry entry = new IPEntry(); entry.country = ipLoc.getCountry(); entry.area = ipLoc.getArea(); // 得到起始IP readIP(offset - 4, b4); entry.beginIp = Util.getIpStringFromBytes(b4); // 得到结束IP readIP(temp, b4); entry.endIp = Util.getIpStringFromBytes(b4); // 添加该记录 ret.add(entry); } } } } catch (IOException e) { LogFactory.log("", Level.ERROR, e); } return ret; }
public IPLocation getIPLocation(String ip) { IPLocation location = new IPLocation(); location.setArea(this.getArea(ip)); location.setCountry(this.getCountry(ip)); return location; }
public IPLocation getCopy() { IPLocation ret = new IPLocation(); ret.country = country; ret.area = area; return ret; }