# 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主机就不需要端口映射了*

2. 花生壳路由器配置 **记得选择启用后提交哦**

如果你的路由器设置上花生壳账号密码还能正常的话,那恭喜你了, 后面的东西就不用看了。本文的主要目的就是这个不稳定
### 三、通过花生壳给的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;
}