# hskserver **Repository Path**: swjsj.com/hskserver ## Basic Information - **Project Name**: hskserver - **Description**: 使用家庭ADSL宽带或光纤,利用花生壳架设自己的服务服务器,解决路由器上自带花生壳域名同步不及时的问题,IP地址不能及时的更新 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 25 - **Forks**: 5 - **Created**: 2015-11-26 - **Last Updated**: 2024-09-05 ## Categories & Tags **Categories**: networklib **Tags**: None ## README #hskserver 作为一个程序员,如果有自己的服务器,做个svn什么的,放点代码, 做个网站,存放一些数据, 在外面通过网络能直接访问, 这也算是一个比较美好的事情吧。当然,在天朝, 就不要期望在自己的服务器上做个外网访问的网站了。除非你能不用80端口来做网站,还有人访问,否者的话, 就放弃吧。不过自己用的网站,或者测试用的, 还是没有问题的。下面就说说我自己的配置 ### 一、前置条件 + 一台电脑 (稳定的,性能不用太好*省电*,最好是台式机,你总不能天天开着笔记本放那,为了稳定性,还是放弃windows吧,server也不行,建议还是弄个linux,我对ubuntu熟悉一点, 所以就用ubuntu了。) + 宽带(这个就不说了,网速越快越好了,不过如果你家里的网络是小区宽带,宽带通什么的, 直接放弃吧,没有外网ip,什么都做不了, 我用的是联通的20M光纤,坑爹的联通上传速度是300k左右,在这里要痛诉一下假宽带,如果ADSL基本上都能实现的) + _ 花生壳账号 (这不需要有独立的域名, 现在绑定独立域名好像收费了,我绑定的早,免费的用的挺好,就直接上http://hsk.oray.com/去注册申请一个吧,用花生壳提供的二级域名就好了,这个主要用来获取唯一的公网IP用的)_ 这里直接使用阿里云域名更好, 花生壳好像不支持了, 使用aliyun的sdk,调用更新域名地址就ok了 ### 二、获取公网IP 完成以下3个步骤就可以了 1.修改resource目录下的application.properties文件 2.使用maven的package方法打包 3.nohup java -jar hskserver-1.0-SNAPSHOT.jar & 其实最好的方法也是最简单的方法,就是在路由器上设置, 我的路由器上也能设置, 就是丫的不稳定, 也不知道是不是花生壳免费的不稳定,反正稳定不了几天 路由器配置主要是两个地方 1. DMZ主机 ![DMZ主机设置方式](http://img.jishijun.cn/upload/img/20151126/20151126110150.jpg) 这个方式简单,但是正个服务器也都暴露在外网了,如果你熟悉端口, 一个一个端口映射也没有关系。*配置了DMZ主机就不需要端口映射了* ![端口映射](http://img.jishijun.cn/upload/img/20151126/20151126110348.png) 2. 花生壳路由器配置 **记得选择启用后提交哦** ![花生壳配置图片](http://img.jishijun.cn/upload/img/20151126/20151126110455.jpg) 如果你的路由器设置上花生壳账号密码还能正常的话,那恭喜你了, 后面的东西就不用看了。本文的主要目的就是这个不稳定 ### 三、通过花生壳给的API,动态的提交请求, 同步域名解析地址 由于路由器的不稳定, 所以还是通过自己的程序来实现, 花生壳的API说明地址 >其实主要做的事情就是获取你路由器的公网IP地址: 和实际上域名映射的IP地址比较,如果不一样的,就需要提交请求, 让花生壳解析到正确的IP地址上。 参考上面的连接的地址的《例子》 1.使用URL验证 适用于浏览器或应用程序(fetch, curl, lwp-request),可以在URL中包含验证信息。 http://username:password@ddns.oray.com/ph/update?hostname=yourhostname&myip=ipaddress 这个方式在浏览器的时候调用特别有用, 但是我用nodejs的ajax异步请求的时候总是出现不能反回正确的情况。 我直接用java来模拟模拟浏览器提交了,反正特别的稳定。 2.原始HTTP GET请求 实际的HTTP请求,类似下面的代码。 其中 base-64-authorization 请使用 Base64 加密 username:password 后的字符替换。 GET /ph/update?hostname=yourhostname&myip=ipaddress HTTP/1.0 Host: ddns.oray.com Authorization: Basic base-64-authorization User-Agent: Oray 请注意必须使用GET请求,POST是不被允许的。 这个方法应该是一样的, 我没有试过, >我实现的方式,是通过定时器的方式, 定时1分钟执行一次。来检测IP地址是否有变化,如果有,参照API提交,并且发邮件通知, 这个域名解析不是实时生效饿, 如果你着急用, 能通过邮件,获取到IP地址也是不错的,通过IP来连接自己的主机,如果没有变化, 不做任何操作 实现中主要的代码信息 获取远程域名对应的IP地址 public static String getRemountIPByHSK() { Document doc = null; try { URL url = new URL("http://ddns.oray.com/checkip"); doc = Jsoup.parse(url, 10 * 1000); Elements es = doc.select("body"); String ipstr = es.text(); Pattern pattern = Pattern .compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"); // 正则表达式匹配格式 Matcher matcher = pattern.matcher(ipstr); if (matcher.find()) { String srcStr = matcher.group(); // 这里得到的ip return srcStr; } } catch (IOException e) { Logger.getLogger("publish").error(e.getMessage(), e); return getRemountIP(); } return ""; } 获取本地路由器的IP public static String getIPByName(String name) { InetAddress address = null; String ip = ""; try { address = InetAddress.getByName(name); ip = address.getHostAddress().toString(); } catch (Exception e) { Logger.getLogger("publish").error(e.getMessage(), e); } return ip; } 需要更新IP的方法 **注册花生壳的时候送你的二级域名** 这个一定你的申请时二级域名 public static String sendGet(String ip) { String result = ""; BufferedReader in = null; try { // String urlNameString = url + "?" + param; String url = "http://ddns.oray.com/ph/update?hostname=注册花生壳的时候送你的二级域名&myip=" + ip; URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection .setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); connection.setRequestProperty("Connection", "Keep-Alive"); connection.setRequestProperty("User-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); connection.setRequestProperty("Authorization", "Authorization"); // 建立实际的连接 connection.connect(); // 获取所有响应头字段 Map> map = connection.getHeaderFields(); // 遍历所有的响应头字段 for (String key : map.keySet()) { Logger.getLogger("publish").info(key + "--->" + map.get(key)); } // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader( connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送GET请求出现异常!" + e); Logger.getLogger("publish").error(e.getMessage(), e); } // 使用finally块来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { Logger.getLogger("publish").error(e2.getMessage(), e2); } } return result; }