背景:博主本是一位Windows桌面应用程序开发工程师,对网络通信一知半解。一日老婆逛完某宝,问:“为什么他们知道我的地址呢,他们是怎么获取我的地址的呢?”
创新互联建站主要从事网站制作、网站建设、网页设计、企业做网站、公司建网站等业务。立足成都服务木垒哈萨克,十余年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:13518219792顺着这个问题我们的探秘开始:
第一步:简单的服务搭建
思路,通过HttpListener在本地搭建一个简易的服务器,开发程序为控制台接口,核心类 HttpListenerService:
方法 Start()开启线程池针对指定IP进行监听,本地的端口选取的9527(周星驰唐伯虎点秋香在华府的编号)
public void Start(object obj) { try { //指定身份验证 Anonymous匿名访问 _httpListener.AuthenticationSchemes = AuthenticationSchemes.Anonymous; //GetLocalIpAddress()----获取本地IP的方法 _httpListener.Prefixes.Add("http://" + GetLocalIpAddress() + ":9527/"); _httpListener.Start(); //等待请求连接 while (true) { //等待请求连接 //没有请求则GetContext处于阻塞状态 var ctx = _httpListener.GetContext(); ThreadPool.QueueUserWorkItem(TaskProc, ctx); } } catch (Exception ex) { throw; } }
第二步:获取客户端request的IP地址
网上查询了很多例子,感觉太复杂了,自己通过VS的快速监视功能发现有一个属性 RemoteEndPoint 可以获取客户端IP和端口号 ,其实应该根据Get和POST进行区分,为了方便暂时省略
1 private void TaskProc(object o) 2 { 3 try 4 {; 5 var ctx = (HttpListenerContext) o; 6 string ipAddress = null; 7 if (ctx.Request.RemoteEndPoint != null) 8 { 9 ipAddress = ctx.Request.RemoteEndPoint.Address.ToString();10 } 11 //后面的暂时不用看,已经获取到客户端访问IP12 var encoding = Encoding.GetEncoding("gb2312");13 var callbackData = JsonConvert.SerializeObject(IpGetCity(GetOuterNetIp()));14 var data = encoding.GetBytes(callbackData);15 ctx.Response.StatusCode = 200;16 ctx.Response.Close(data, false);17 }18 catch (Exception ex)19 {20 }21 }
第三步:如何根据客户端的IP获取,客户端所在的地址,因为事情起源来自淘宝,所以就 查询淘宝是否有类似的接口,果然经过搜索后查到 http://ip.taobao.com/service/getIpInfo.php?ip= 客户IP的Json对象,通过Fiddler解析返回数据,创建对应Json格式对象,封装获取方法
1 public static Result IpGetCity(string ipAddres) 2 { 3 try 4 { 5 if (!ValidateIpAddress(ipAddres)) return null; 6 7 var url = new Uri("http://ip.taobao.com/service/getIpInfo.php?ip=" + ipAddres); 8 var request = (HttpWebRequest) WebRequest.Create(url); 9 request.Timeout = 1000*5;10 request.KeepAlive = false;11 request.Method = "GET";12 var resoponse = request.GetResponse();13 string pageHtml;14 // ReSharper disable once AssignNullToNotNullAttribute15 using (var stream = new StreamReader(resoponse.GetResponseStream()))16 {17 pageHtml = stream.ReadToEnd();18 } 19 var data = JsonConvert.DeserializeObject(pageHtml);20 return data;21 }22 catch (WebException webEx)23 {24 throw;25 }26 }
第四步:测试。 因为本地是局域网,发送IP地址后返回肯定为空,先尝试查询本地外网IP,那么如何获取本地的外网IP呢?还是同前面的思路一样,网络查询类似的接口,百度一下直接根据第一个搜索的结果查询,http://1212.ip138.com,建立webrequest请求,抓取Html数据
1 public static string GetOuterNetIp() 2 { 3 var tempIp = ""; 4 try 5 { 6 WebRequest wr = (HttpWebRequest) WebRequest.Create("http://1212.ip138.com"); 7 var stream = wr.GetResponse().GetResponseStream(); 8 var sr = new StreamReader(stream, Encoding.GetEncoding("gb2312")); 9 var all = sr.ReadToEnd(); 10 //读取网站的数据11 var start = all.IndexOf("您的IP是:[", StringComparison.Ordinal) + 7;12 var end = all.IndexOf("]", start, StringComparison.Ordinal);13 tempIp = all.Substring(start, end - start);14 sr.Close();15 stream.Close();16 }17 catch28 {19 // ignored20 }21 return tempIp;22 }
但是问题出现了,为什么我浏览器获取的数据可以得到本机的IP,但是我建立的连接获取的请求却是这样
经过分析后发现,这个网址试用iframe框架进行处理,无法获取到frame框架的内部信息,然后抓去frame信息发现其实他真正请求的路径为 http://1212.ip138.com/ic.asp,该网站的编码格式为gb2312,再次发送请求获取返回数据:
虽然大概了解的一些,但是比如用户用代理服务器访问等一系列的问题还是需要我继续去探索!
另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。