今天YY给了我一大串dns server的ip,然后提出将这些ip物理位置显示在世界地图上(仅仅显示每个地区有几个dns server就好),苦逼了一下午,总算告一段落。把里面关键的点贴上来以后看。。。
1、地图插件用的Echarts(http://echarts.baidu.com/)
2、解析ip的物理地址用的nodejs
先上张效果图:
dns ip文件长这个样子:
1 180.222.176.221 2 122.231.179.214 3 69.140.168.9 4 124.217.245.110 5 162.144.74.160 6 23.94.187.47 7 72.231.182.234 8 76.99.144.59 9 5.133.217.42 10 217.15.116.80 11 175.244.198.109 12 179.158.154.41 13 42.80.173.8 14 220.120.58.209 15 46.28.68.152 16 199.204.250.165 17 198.84.75.91 18 69.249.37.227 19 187.177.77.195 20 122.133.187.164 21 84.108.142.88 22 217.129.35.190 23 68.54.40.245 24 93.69.100.139 25 184.53.155.254 26 //此处省略好多好多行
ip物理地址库和示例代码请戳:http://tool.17mon.cn/ipdb.html#userconsent#
这里我选用的nodejs版本(其实Python实现起来真心简单啊。。。可作为前端狗,先把nodejs玩顺溜再说)
ip解析:ip.js(这个主要是看里面的接口。。。会用就OK,以后有空儿了可以琢磨下实现原理)
1 var fs = require('fs'); 2 var dns = require('dns'); 3 4 var _17monIpDbPath = './17monipdb.dat'; 5 6 var loadBinaryData = function(filepath){ 7 var fd = fs.openSync(filepath, 'r'); 8 var indexLengthBuffer = new Buffer(4); 9 var chunkSize = 102400, 10 chunkBuffer, 11 chunks = []; 12 13 var readLength = 0, 14 bufferLength = 0; 15 16 while (true) { 17 chunkBuffer = new Buffer(chunkSize); 18 readLength = fs.readSync(fd, chunkBuffer, 0, chunkSize, bufferLength); 19 bufferLength += readLength; 20 chunks.push(chunkBuffer); 21 if (readLength < chunkSize) break; 22 } 23 fs.closeSync(fd); 24 25 return Buffer.concat(chunks); 26 }; 27 28 var IpFind = function(ip){ 29 var ipArray = ip.trim().split('.'), 30 ip2long = function(ip){return new Buffer(ip.trim().split('.')).readInt32BE(0)}, 31 ipInt = ip2long(ip); 32 33 var offset = dataBuffer.readInt32BE(0); 34 var indexBuffer = dataBuffer.slice(4, offset - 4 + 4); 35 var tmp_offset = ipArray[0] * 4, max_comp_len = offset - 1028, index_offset = -1, index_length = -1, start = indexBuffer.slice(tmp_offset, tmp_offset + 4).readInt32LE(0); 36 for (start = start * 8 + 1024; start < max_comp_len; start += 8) { 37 if (indexBuffer.slice(start, start + 4).readInt32BE(0) >= ipInt) { 38 index_offset = ((indexBuffer[start + 6] << 16) + (indexBuffer[start + 5] << 8) + indexBuffer[start + 4]); 39 index_length = indexBuffer[start + 7]; 40 break; 41 } 42 } 43 if (index_offset == -1 || index_length == -1) { 44 return []; 45 } else { 46 return dataBuffer.slice(offset + index_offset - 1024, offset + index_offset - 1024 + index_length).toString('utf-8').split(" "); 47 } 48 }; 49 50 var dataBuffer = loadBinaryData(_17monIpDbPath); 51 52 exports.find = function(name, callback){ 53 dns.resolve4(name, function (err, addresses) { 54 if (err) { 55 callback(IpFind(name)); 56 } else { 57 callback(IpFind(addresses.shift())); 58 } 59 }); 60 }; 61 exports.findSync = IpFind;
逐行读取txt,使用ip.js里的函数,生成Echarts所要的数据格式:run.js
1 var fs = require('fs'); 2 var IP = require('./ip'); 3 4 var _dnsserver = './dnsserver.txt'; 5 6 fs.readFile(_dnsserver,'utf-8',function(err,data){ 7 var dataIp = []; 8 var dataArr = data.split(/ +/); 9 for(var i=0 ; i < dataArr.length-1 ; i++){ 10 dataIp.push(IP.findSync(dataArr[i])[0]); 11 } 12 var oData = countArr(dataIp); 13 var jsonData = []; 14 for(var attr in oData){ 15 var tempObj = {}; 16 tempObj.name = attr; 17 tempObj.value = oData[attr]; 18 jsonData.push(tempObj); 19 } 20 console.log(jsonData);
//jsonData是我们要的数据格式,大体长这个样子
// [ { name: '日本', value: 55 },
// { name: '中国', value: 240 },
// { name: '美国', value: 489 }]
21 }); 22 23 function countArr(arr){ 24 var o = {}; 25 for(var i = 0, l = arr.length; i < l; i++){ 26 var key = arr[i]; 27 if(!o[key]){ 28 o[key] = 1; 29 } else { 30 o[key]++; 31 } 32 } 33 return o; 34 } 35 /* 异步方法 支持域名 */ 36 //IP.find('116.226.54.188', function(data){ 37 // console.log(data); 38 //}); 39 40 /* 同步方法,不支持域名,仅支持IPv4 */ 41 //console.log(IP.findSync('180.73.134.23'));
运行run.js,结果如下:
然后生成txt,把结果存起来,用jQuery Ajax读取,这时,坑爹的bug来了。。。
先看代码:
1 $(document).ready(function(){ 2 $.ajax({ 3 type: "get", 4 url: 'data.txt',//本地存的文件 5 dataType: 'text', 6 success: function(data) { 7 alert(data);//这个data就是文件内容了 8 } 9 }); 10 });
感觉没任何错误吧。。。IE低下也能粗结果,可是chrome里data就是没值啊没值。。。后来各种查资料才知道,chrome Ajax不能访问本地文件 (http://blog.csdn.net/spring21st/article/details/6109669),之前都是访问的server上的数据,没访问过本地的文件,没遇到过,这回真心长姿势了。。。
最后Echarts使用真心没啥好贴,不过注意下那个版本问题,有时候会粗错