diff --git a/.gitignore b/.gitignore
index 5ee4fa9c418d7e09912b108f8a16c7d2f6198df5..276b620a3209f773fce2ded2dcf51b01a2895e52 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
.idea/*
target/*
*/target/
-jforwarding.sqlite
\ No newline at end of file
+jforwarding.sqlite
+*.iml
\ No newline at end of file
diff --git a/README.md b/README.md
index 5afbae696d1f167bb44c9c6ea206b82aa8e70324..e12e76a4603c72592875335dff46e5efdff56307 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,9 @@
* 可转发本机或局域网内其它任何机器的TCP数据包
### 设置
-
+## 原理
+假设我们需要把一台局域网的80端口暴露出来,我们利用公网服务器的2222端口来转发,那么流程是这样的。
+
## 快速开始
1. 按需修改两个模块下的配置文件,比如几个端口及主机端的服务器地址等。
2. 使用Maven打包,`mvn package`,将会在`target`目录下分别生成服务器端`original-commander-1.0-SNAPSHOT.jar`和主机端`messenger-1.0-SNAPSHOT.jar`。
diff --git a/commander/commander.iml b/commander/commander.iml
deleted file mode 100644
index 343fa55018d89ef37587651e89eb14c723ccdbf6..0000000000000000000000000000000000000000
--- a/commander/commander.iml
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/commander/src/main/java/cn/org/hentai/server/protocol/commander/CommandSession.java b/commander/src/main/java/cn/org/hentai/server/protocol/commander/CommandSession.java
index d022afb23d96e4e10a176340c30603cfb0edffec..6c88e9600edd1ada22a143d72f6d385aa9ea41cd 100644
--- a/commander/src/main/java/cn/org/hentai/server/protocol/commander/CommandSession.java
+++ b/commander/src/main/java/cn/org/hentai/server/protocol/commander/CommandSession.java
@@ -13,6 +13,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.LinkedList;
+import java.util.concurrent.LinkedBlockingQueue;
/**
* Created by Expect on 2018/1/25.
@@ -24,7 +25,7 @@ public class CommandSession extends SocketSession
Socket connection = null;
long lastActiveTime = System.currentTimeMillis();
int testTimeout = 0;
- LinkedList commands = new LinkedList(); // 待下发的指令
+ LinkedBlockingQueue commands = new LinkedBlockingQueue(); // 待下发的指令
public CommandSession(Socket connection)
{
@@ -43,23 +44,39 @@ public class CommandSession extends SocketSession
protected void converse() throws Exception
{
this.connection.setSoTimeout(testTimeout * 2);
- InputStream inputStream = this.connection.getInputStream();
- OutputStream outputStream = this.connection.getOutputStream();
+ final InputStream inputStream = this.connection.getInputStream();
+ final OutputStream outputStream = this.connection.getOutputStream();
// 先读取一个包,确定一下主机端的身份
host = authenticate(inputStream, outputStream);
HostConnectionManager.getInstance().register(host.getId(), this);
Log.debug("主机: " + host.getName() + "己连接...");
-
+ // 保证连接的可用性
+ new Thread(new Runnable(){
+
+ @Override
+ public void run() {
+ while (!timedout())
+ {
+ try {
+ heartBeat(inputStream, outputStream);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ try {
+ Thread.sleep(testTimeout/3);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+ }).start();
while (!timedout())
{
- // 测试连接的可用性
- testConnection(inputStream, outputStream);
-
// 是否有需要下发的指令?
sendCommand(inputStream, outputStream);
-
- Thread.sleep(10);
}
}
@@ -77,9 +94,7 @@ public class CommandSession extends SocketSession
*/
private void sendCommand(InputStream inputStream, OutputStream outputStream) throws Exception
{
- if (commands.size() == 0) return;
- Command cmd = commands.removeFirst();
- if (null == cmd) return;
+ Command cmd = commands.take();
byte[] packet = Packet.create(host.getId(), Packet.ENCRYPT_TYPE_DES, cmd.getCode(), cmd.getBytes(), host.getAccesstoken());
outputStream.write(packet);
outputStream.flush();
@@ -92,9 +107,8 @@ public class CommandSession extends SocketSession
* @param inputStream
* @param outputStream
*/
- private void testConnection(InputStream inputStream, OutputStream outputStream) throws Exception
+ private void heartBeat(InputStream inputStream, OutputStream outputStream) throws Exception
{
- if (System.currentTimeMillis() - lastActiveTime < testTimeout) return;
byte[] data = NonceStr.generate(32).getBytes();
byte[] packet = Packet.create(host.getId(), Packet.ENCRYPT_TYPE_DES, Command.CODE_TEST, data, host.getAccesstoken());
outputStream.write(packet);
@@ -133,6 +147,10 @@ public class CommandSession extends SocketSession
public synchronized void requestForward(int seqId, String nonce, Port port)
{
- commands.add(new StartForwardCommand(seqId, port.getHostIp(), port.getHostPort(), nonce));
+ try {
+ commands.put(new StartForwardCommand(seqId, port.getHostIp(), port.getHostPort(), nonce));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
}
}
diff --git a/commander/src/main/java/cn/org/hentai/server/protocol/proxy/ProxySession.java b/commander/src/main/java/cn/org/hentai/server/protocol/proxy/ProxySession.java
index 57ab125dca8059c53825f84364bffe17450b017d..efb54e3957a9b94489ae86b15863d8ebe84c97f0 100644
--- a/commander/src/main/java/cn/org/hentai/server/protocol/proxy/ProxySession.java
+++ b/commander/src/main/java/cn/org/hentai/server/protocol/proxy/ProxySession.java
@@ -19,6 +19,7 @@ import java.net.SocketTimeoutException;
*/
public class ProxySession extends SocketSession
{
+ private Object obj = new Object();
private Port port; // 主机端ID
private Socket clientConnection; // 客户端连接
private Socket hostConnection; // 被代理的主机端连接
@@ -40,6 +41,9 @@ public class ProxySession extends SocketSession
public void attach(Socket hostConnection)
{
this.hostConnection = hostConnection;
+ synchronized (obj) {
+ obj.notify();
+ }
}
@Override
@@ -61,11 +65,9 @@ public class ProxySession extends SocketSession
long stime = System.currentTimeMillis();
while (this.hostConnection == null)
{
- if (System.currentTimeMillis() - stime > connectTimeout)
- {
- throw new SocketTimeoutException("等待主机端连接超时");
+ synchronized (obj) {
+ obj.wait(connectTimeout);
}
- sleep(10);
}
Log.debug("主机端己连接");
@@ -95,6 +97,10 @@ public class ProxySession extends SocketSession
{
// 主机端到客户端,需要解密后转发
decryptAndTransfer(hostIS, clientOS, hostBufLength);
+// 如果不关闭 浏览器访问有更好的性能
+// ab -n 1 -c 1 http://127.0.0.1:2222/ 会触发超时
+// clientConnection.close();
+// return;
}
if (hostBufLength + clientBufLength == 0) Thread.sleep(1);
}
@@ -120,7 +126,8 @@ public class ProxySession extends SocketSession
// to.write(buf, 0, len);
}
buf = null;
- buf = DES.decrypt(baos.toByteArray(), this.nonce);
+// buf = DES.decrypt(baos.toByteArray(), this.nonce);
+ buf = baos.toByteArray();
// to.write(ByteUtils.toBytes(buf.length));
to.write(buf);
to.flush();
@@ -141,7 +148,8 @@ public class ProxySession extends SocketSession
// to.write(buf, 0, len);
}
buf = null;
- buf = DES.encrypt(baos.toByteArray(), this.nonce);
+// buf = DES.encrypt(baos.toByteArray(), this.nonce);
+ buf = baos.toByteArray();
to.write((byte)0xfa);
to.write((byte)0xfa);
to.write((byte)0xfa);
diff --git a/commander/src/main/resources/application.properties b/commander/src/main/resources/application.properties
index 6a7c4ce63a5363e618e06f8305bc033008a5ddac..fa5d47b7b51441db57d9d3c7c2a43ff1b2b4d941 100644
--- a/commander/src/main/resources/application.properties
+++ b/commander/src/main/resources/application.properties
@@ -1,24 +1,24 @@
-
+
server.address=0.0.0.0
server.port=8888
-# ָ˿
+# 指令服务器监听端口
server.command.port = 12121
-# ת˿
+# 转发服务器监听端口
server.forward.port = 11221
-# ˵Ӳط룩
+# 服务器端的连接测试包重发间隔(毫秒)
server.test-packet.timeout = 30000
-# û½ỰЧʱӣ
+# 用户登陆会话有效时长(分钟)
user.token.expire.minutes=1440
-# ûaccesstokenKEY
+# 用户accesstoken加密KEY
user.token.key=VJN42837P0QJHVEY29
-# 趨ftlļ·
+# 设定ftl文件路径
spring.freemarker.template-loader-path=classpath:/templates
-# 趨̬ļ·js,css
+# 设定静态文件路径,js,css等
spring.mvc.static-path-pattern=/static/**
# sqlite url
diff --git a/messenger/messenger.iml b/messenger/messenger.iml
deleted file mode 100644
index 73f608bd65fdb4cf601b3ac4115367ee0f071ffd..0000000000000000000000000000000000000000
--- a/messenger/messenger.iml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/messenger/src/main/java/cn/org/hentai/messenger/protocol/CommandListener.java b/messenger/src/main/java/cn/org/hentai/messenger/protocol/CommandListener.java
index 88ee468fc552b72b1bda42a16dc4abf36f58e9ed..aaccb00208e4a1fbec5ebe8c0b46458ba14631cd 100644
--- a/messenger/src/main/java/cn/org/hentai/messenger/protocol/CommandListener.java
+++ b/messenger/src/main/java/cn/org/hentai/messenger/protocol/CommandListener.java
@@ -53,18 +53,17 @@ public class CommandListener implements Runnable
byte[] resp, packet = Packet.create(hostId, Packet.ENCRYPT_TYPE_DES, cmd, accessToken);
outputStream.write(packet);
outputStream.flush();
- resp = Packet.read(inputStream, true);
+ Packet.read(inputStream, true);
Log.debug("己连接到服务器端...");
lastExchangeTime = System.currentTimeMillis();
// 2. 等待服务器的心跳测试包或是指令包
while (true)
{
- resp = Packet.read(inputStream);
+ resp = Packet.read(inputStream,true);
if (null == resp)
{
if (System.currentTimeMillis() - lastExchangeTime > iowaitTimeout) break;
- Thread.sleep(100);
continue;
}
diff --git a/messenger/src/main/java/cn/org/hentai/messenger/protocol/ForwardWorker.java b/messenger/src/main/java/cn/org/hentai/messenger/protocol/ForwardWorker.java
index 28b851f3be76fc6105d8848a0ddc41389507ae55..d6b6f717d09e3a08a72e40fadac9157609dd5410 100644
--- a/messenger/src/main/java/cn/org/hentai/messenger/protocol/ForwardWorker.java
+++ b/messenger/src/main/java/cn/org/hentai/messenger/protocol/ForwardWorker.java
@@ -125,7 +125,8 @@ public class ForwardWorker extends Thread
// to.write(buf, 0, len);
}
buf = null;
- buf = DES.decrypt(baos.toByteArray(), this.nonce);
+// buf = DES.decrypt(baos.toByteArray(), this.nonce);
+ buf = baos.toByteArray();
// to.write(ByteUtils.toBytes(buf.length));
to.write(buf);
to.flush();
@@ -146,7 +147,8 @@ public class ForwardWorker extends Thread
// to.write(buf, 0, len);
}
buf = null;
- buf = DES.encrypt(baos.toByteArray(), this.nonce);
+// buf = DES.encrypt(baos.toByteArray(), this.nonce);
+ buf = baos.toByteArray();
to.write((byte)0xfa);
to.write((byte)0xfa);
to.write((byte)0xfa);