From 3a7c5d4512d5890798ad00e0942808258c88e84f Mon Sep 17 00:00:00 2001
From: SpringHgui <740360381@qq.com>
Date: Fri, 9 Jul 2021 00:32:51 +0800
Subject: [PATCH] =?UTF-8?q?=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
FastTunnel.Client/appsettings.json | 22 ++-
FastTunnel.Core/Client/FastTunnelClient.cs | 106 +++++++++++++--
.../Dispatchers/HttpDispatcherV2.cs | 34 +++--
FastTunnel.Core/FastTunnel.Core.csproj | 2 +-
.../Handlers/Client/HttpRequestHandler.cs | 19 ++-
.../Handlers/Client/NewSSHHandler.cs | 9 +-
.../Handlers/Server/SwapMessageHandler.cs | 6 +-
FastTunnel.Core/Listener/ClientListenerV2.cs | 4 +-
FastTunnel.Core/Listener/HttpListenerV2.cs | 3 +-
FastTunnel.Core/Server/AsyncUserToken.cs | 2 +
FastTunnel.Core/Server/BufferManeger.cs | 2 +-
FastTunnel.Core/Server/PipeHepler.cs | 5 +-
FastTunnel.Core/Server/Server.cs | 32 +++--
.../Services/ServiceFastTunnelClient.cs | 1 -
FastTunnel.Core/Sockets/AsyncSocketSwap.cs | 1 -
FastTunnel.Core/Sockets/ConnectSocket.cs | 55 ++++++++
FastTunnel.Core/Sockets/SocketSwap.cs | 128 ++++++++++--------
.../Utility/Extensions/DateTimeExtensions.cs | 19 +++
addhost.bat | 4 +-
19 files changed, 345 insertions(+), 109 deletions(-)
create mode 100644 FastTunnel.Core/Sockets/ConnectSocket.cs
create mode 100644 FastTunnel.Core/Utility/Extensions/DateTimeExtensions.cs
diff --git a/FastTunnel.Client/appsettings.json b/FastTunnel.Client/appsettings.json
index 5ef2270..c22829e 100644
--- a/FastTunnel.Client/appsettings.json
+++ b/FastTunnel.Client/appsettings.json
@@ -2,7 +2,7 @@
"Logging": {
"LogLevel": {
// Trace Debug Information Warning Error
- "Default": "Information",
+ "Default": "Trace",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
@@ -10,8 +10,8 @@
"ClientSettings": {
"Server": {
// 服务端ip/域名
- "ServerAddr": "test.cc",
- //"ServerAddr": "127.0.0.1",
+ //"ServerAddr": "my.com",
+ "ServerAddr": "127.0.0.1",
// 服务端监听的通信端口
"ServerPort": 1271
},
@@ -21,13 +21,18 @@
"LocalIp": "127.0.0.1",
// 站点监听的端口号
- "LocalPort": 9529,
+ "LocalPort": 8090,
// 子域名, 访问本站点时的url为 http://{SubDomain}.{WebDomain}:{WebProxyPort}/
"SubDomain": "test" // test.test.cc
// 附加域名,需要解析域名A记录至服务的ip地址)
// "WWW": [ "www.abc.com", "test111.test.cc" ]
+ },
+ {
+ "LocalIp": "127.0.0.1",
+ "LocalPort": 8091,
+ "SubDomain": "test1"
}
],
@@ -38,9 +43,14 @@
*/
"SSH": [
{
- "LocalIp": "test.cc",
+ "LocalIp": "127.0.0.1",
"LocalPort": 8090,
- "RemotePort": 9999
+ "RemotePort": 7090
+ },
+ {
+ "LocalIp": "127.0.0.1",
+ "LocalPort": 8091,
+ "RemotePort": 7091
},
{
"LocalIp": "192.168.0.91",
diff --git a/FastTunnel.Core/Client/FastTunnelClient.cs b/FastTunnel.Core/Client/FastTunnelClient.cs
index f2056b4..ab42ea4 100644
--- a/FastTunnel.Core/Client/FastTunnelClient.cs
+++ b/FastTunnel.Core/Client/FastTunnelClient.cs
@@ -191,20 +191,103 @@ namespace FastTunnel.Core.Client
// 心跳开始
timer_heart.Start();
- await new PipeHepler(_client, ProceccLine).ProcessLinesAsync();
+ var th = new Thread(ReceiveServer);
+ th.Start(_client);
+ //await new PipeHepler(_client, ProceccLine).ProcessLinesAsync();
+ }
+
+ private void ReceiveServer(object obj)
+ {
+ var client = obj as Socket;
+ byte[] buffer = new byte[1024];
+
+ string lastBuffer = string.Empty;
+ int n = 0;
+
+ while (true)
+ {
+ try
+ {
+ n = client.Receive(buffer);
+ if (n == 0)
+ {
+ client.Shutdown(SocketShutdown.Both);
+ break;
+ }
+ }
+ ///
+ catch (SocketException socketEx)
+ {
+ // Connection timed out.
+ if (socketEx.ErrorCode == 10060)
+ {
+ _logger.LogInformation("Connection timed out");
+ }
+ else
+ {
+ _logger.LogError(socketEx);
+ }
+
+ break;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex);
+ break;
+ }
+
+ string words = Encoding.UTF8.GetString(buffer, 0, n);
+ if (!string.IsNullOrEmpty(lastBuffer))
+ {
+ words = lastBuffer + words;
+ lastBuffer = null;
+ }
+
+ var msgs = words.Split("\n");
+
+ _logger.LogDebug("recive from server:" + words);
+
+ try
+ {
+ foreach (var item in msgs)
+ {
+ if (string.IsNullOrEmpty(item))
+ continue;
+
+ if (item.EndsWith("}"))
+ {
+ HandleServerRequest(item);
+ }
+ else
+ {
+ lastBuffer = item;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex.Message);
+ continue;
+ }
+ }
+
+ _logger.LogInformation("stop receive from server");
}
private bool ProceccLine(Socket socket, byte[] line)
{
- try
+ Task.Run(() =>
{
- var cmd = Encoding.UTF8.GetString(line);
- HandleServerRequest(cmd);
- }
- catch (Exception ex)
- {
- _logger.LogError(ex);
- }
+ try
+ {
+ var cmd = Encoding.UTF8.GetString(line);
+ HandleServerRequest(cmd);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex);
+ }
+ });
return true;
}
@@ -212,6 +295,11 @@ namespace FastTunnel.Core.Client
private void HandleServerRequest(string words)
{
var Msg = JsonConvert.DeserializeObject>(words);
+ if (Msg.MessageType!= MessageType.Heart)
+ {
+ _logger.LogDebug($"HandleServerRequest {words}");
+ }
+
IClientHandler handler;
switch (Msg.MessageType)
{
diff --git a/FastTunnel.Core/Dispatchers/HttpDispatcherV2.cs b/FastTunnel.Core/Dispatchers/HttpDispatcherV2.cs
index 2b2fb9f..5fc22ec 100644
--- a/FastTunnel.Core/Dispatchers/HttpDispatcherV2.cs
+++ b/FastTunnel.Core/Dispatchers/HttpDispatcherV2.cs
@@ -12,6 +12,7 @@ using System.Text.RegularExpressions;
using System.Net.Http;
using System.IO;
using FastTunnel.Core.Server;
+using System.Diagnostics;
namespace FastTunnel.Core.Dispatchers
{
@@ -32,7 +33,10 @@ namespace FastTunnel.Core.Dispatchers
public void Dispatch(AsyncUserToken token, string words)
{
- _logger.LogDebug("=======Dispatch HTTP========");
+ _logger.LogDebug($"=======Dispatch HTTP {token.RequestId}========");
+
+ Stopwatch sw = new Stopwatch();
+ sw.Start();
// 1.检查白名单
try
@@ -54,8 +58,6 @@ namespace FastTunnel.Core.Dispatchers
_logger.LogError(ex);
}
- _logger.LogDebug("=======Dispatch Matches========");
-
string Host;
MatchCollection collection = Regex.Matches(words, pattern);
if (collection.Count == 0)
@@ -74,7 +76,7 @@ namespace FastTunnel.Core.Dispatchers
_logger.LogDebug(Host.Replace("\r", ""));
var domain = Host.Split(":")[1].Trim();
- _logger.LogDebug($"=======Dispatch domain:{domain}========");
+ _logger.LogDebug($"=======Dispatch domain:{domain} {token.RequestId} ========");
// 判断是否为ip
if (IsIpDomian(domain))
@@ -87,34 +89,36 @@ namespace FastTunnel.Core.Dispatchers
WebInfo web;
if (!_fastTunnelServer.WebList.TryGetValue(domain, out web))
{
- _logger.LogDebug($"=======Dispatch 未登录========");
+ _logger.LogDebug($"=======站点未登录 {token.RequestId}========");
HandlerClientNotOnLine(token.Socket, domain);
return;
}
- _logger.LogDebug($"=======Dispatch 已找到========");
- var msgid = Guid.NewGuid().ToString();
- _fastTunnelServer.RequestTemp.TryAdd(msgid, new NewRequest
+ _logger.LogDebug($"=======找到映射的站点 {token.RequestId}========");
+ _fastTunnelServer.RequestTemp.TryAdd(token.RequestId, new NewRequest
{
CustomerClient = token.Socket,
Buffer = token.Recived
});
- _logger.LogDebug($"=======Dispatch 发送msg========");
-
try
{
- _logger.LogDebug($"=======OK========");
- web.Socket.SendCmd(new Message { MessageType = MessageType.S_NewCustomer, Content = new NewCustomerMassage { MsgId = msgid, WebConfig = web.WebConfig } });
+ sw.Stop();
+ _logger.LogDebug($"[寻找路由耗时]:{sw.ElapsedMilliseconds}ms");
- _logger.LogDebug($"=======Dispatch OK========");
+ sw.Restart();
+ web.Socket.SendCmd(new Message { MessageType = MessageType.S_NewCustomer, Content = new NewCustomerMassage { MsgId = token.RequestId, WebConfig = web.WebConfig } });
+
+ sw.Stop();
+ _logger.LogDebug($"[发送NewCustomer指令耗时]:{sw.ElapsedMilliseconds}");
+
+ _logger.LogDebug($"=======发送请求成功 {token.RequestId}========");
}
catch (Exception)
{
+ _logger.LogDebug($"=======客户端不在线 {token.RequestId}========");
HandlerClientNotOnLine(token.Socket, domain);
- _logger.LogDebug($"=======Dispatch 移除========");
-
// 移除
_fastTunnelServer.WebList.TryRemove(domain, out _);
}
diff --git a/FastTunnel.Core/FastTunnel.Core.csproj b/FastTunnel.Core/FastTunnel.Core.csproj
index 5ffec5a..e5e742f 100644
--- a/FastTunnel.Core/FastTunnel.Core.csproj
+++ b/FastTunnel.Core/FastTunnel.Core.csproj
@@ -18,7 +18,7 @@
git
FastTunnel.Core
FastTunnel.Core
- 1.1.2
+ 1.1.3
diff --git a/FastTunnel.Core/Handlers/Client/HttpRequestHandler.cs b/FastTunnel.Core/Handlers/Client/HttpRequestHandler.cs
index 9350ba2..56b99c3 100644
--- a/FastTunnel.Core/Handlers/Client/HttpRequestHandler.cs
+++ b/FastTunnel.Core/Handlers/Client/HttpRequestHandler.cs
@@ -10,24 +10,41 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using FastTunnel.Core.Sockets;
+using Microsoft.Extensions.Logging;
+using FastTunnel.Core.Utility.Extensions;
namespace FastTunnel.Core.Handlers.Client
{
public class HttpRequestHandler : IClientHandler
{
+ ILogger _logger;
+
+ public HttpRequestHandler(ILogger logger)
+ {
+ _logger = logger;
+ }
+
public void HandlerMsg(FastTunnelClient cleint, Message Msg)
{
var request = Msg.Content.ToObject();
+ var interval = long.Parse(DateTime.Now.GetChinaTicks()) - long.Parse(request.MsgId.Split('_')[0]);
+
+ _logger.LogDebug($"Start SwapMassage {request.MsgId} 延迟时间:{interval}ms");
+
var connecter = new DnsSocket(cleint.Server.ServerAddr, cleint.Server.ServerPort);
connecter.Connect();
connecter.Send(new Message { MessageType = MessageType.C_SwapMsg, Content = new SwapMassage(request.MsgId) });
+ _logger.LogDebug($"连接server成功 {request.MsgId}");
var localConnecter = new DnsSocket(request.WebConfig.LocalIp, request.WebConfig.LocalPort);
try
{
localConnecter.Connect();
+ _logger.LogDebug($"连接本地成功 {request.MsgId}");
+
+ new SocketSwap(connecter.Socket, localConnecter.Socket, _logger, request.MsgId).StartSwap();
}
catch (SocketException sex)
{
@@ -59,8 +76,6 @@ namespace FastTunnel.Core.Handlers.Client
localConnecter.Close();
throw;
}
-
- new SocketSwap(connecter.Socket, localConnecter.Socket).StartSwap();
}
}
}
diff --git a/FastTunnel.Core/Handlers/Client/NewSSHHandler.cs b/FastTunnel.Core/Handlers/Client/NewSSHHandler.cs
index b2dbd17..bf0b62a 100644
--- a/FastTunnel.Core/Handlers/Client/NewSSHHandler.cs
+++ b/FastTunnel.Core/Handlers/Client/NewSSHHandler.cs
@@ -6,11 +6,18 @@ using System;
using System.Collections.Generic;
using System.Text;
using FastTunnel.Core.Sockets;
+using Microsoft.Extensions.Logging;
namespace FastTunnel.Core.Handlers.Client
{
public class NewSSHHandler : IClientHandler
{
+ ILogger _logger;
+ public NewSSHHandler(ILogger logger)
+ {
+ _logger = logger;
+ }
+
public void HandlerMsg(FastTunnelClient cleint, Message Msg)
{
var request_ssh = Msg.Content.ToObject();
@@ -21,7 +28,7 @@ namespace FastTunnel.Core.Handlers.Client
var localConnecter_ssh = new DnsSocket(request_ssh.SSHConfig.LocalIp, request_ssh.SSHConfig.LocalPort);
localConnecter_ssh.Connect();
- new SocketSwap(connecter_ssh.Socket, localConnecter_ssh.Socket).StartSwap();
+ new SocketSwap(connecter_ssh.Socket, localConnecter_ssh.Socket, _logger, request_ssh.MsgId).StartSwap();
}
}
}
diff --git a/FastTunnel.Core/Handlers/Server/SwapMessageHandler.cs b/FastTunnel.Core/Handlers/Server/SwapMessageHandler.cs
index 61790b3..5c14958 100644
--- a/FastTunnel.Core/Handlers/Server/SwapMessageHandler.cs
+++ b/FastTunnel.Core/Handlers/Server/SwapMessageHandler.cs
@@ -28,10 +28,14 @@ namespace FastTunnel.Core.Handlers.Server
var SwapMsg = msg.Content.ToObject();
NewRequest request;
+ _logger.LogDebug($"响应NewCustomer:{SwapMsg.msgId}");
if (!string.IsNullOrEmpty(SwapMsg.msgId) && server.RequestTemp.TryGetValue(SwapMsg.msgId, out request))
{
server.RequestTemp.TryRemove(SwapMsg.msgId, out _);
- new SocketSwap(request.CustomerClient, client)
+
+ _logger.LogDebug($"SwapMassage:{SwapMsg.msgId}");
+
+ new SocketSwap(request.CustomerClient, client, _logger, SwapMsg.msgId)
.BeforeSwap(() =>
{
if (request.Buffer != null) client.Send(request.Buffer);
diff --git a/FastTunnel.Core/Listener/ClientListenerV2.cs b/FastTunnel.Core/Listener/ClientListenerV2.cs
index 54b3b77..7914f98 100644
--- a/FastTunnel.Core/Listener/ClientListenerV2.cs
+++ b/FastTunnel.Core/Listener/ClientListenerV2.cs
@@ -42,10 +42,10 @@ namespace FastTunnel.Core.Listener
_heartHandler = new HeartMessageHandler();
_swapMsgHandler = new SwapMessageHandler(_logger);
- server = new Server.Server(1000, 100);
+ server = new Server.Server(2000, 100, _logger);
}
- public void Start(int backlog = 100)
+ public void Start()
{
IPAddress ipa = IPAddress.Parse(ListenIp);
IPEndPoint localEndPoint = new IPEndPoint(ipa, ListenPort);
diff --git a/FastTunnel.Core/Listener/HttpListenerV2.cs b/FastTunnel.Core/Listener/HttpListenerV2.cs
index 29720df..1f72e40 100644
--- a/FastTunnel.Core/Listener/HttpListenerV2.cs
+++ b/FastTunnel.Core/Listener/HttpListenerV2.cs
@@ -30,7 +30,7 @@ namespace FastTunnel.Core.Listener
this.ListenIp = ip;
this.ListenPort = port;
- server = new Server.Server(1000, 512);
+ server = new Server.Server(500, 512, _logger);
}
public void Start(IListenerDispatcher requestDispatcher, int backlog = 100)
@@ -49,7 +49,6 @@ namespace FastTunnel.Core.Listener
{
try
{
- Console.WriteLine(words);
_requestDispatcher.Dispatch(token, words);
return false;
}
diff --git a/FastTunnel.Core/Server/AsyncUserToken.cs b/FastTunnel.Core/Server/AsyncUserToken.cs
index fbf0011..9a66c0c 100644
--- a/FastTunnel.Core/Server/AsyncUserToken.cs
+++ b/FastTunnel.Core/Server/AsyncUserToken.cs
@@ -14,5 +14,7 @@ namespace FastTunnel.Core.Server
public string MassgeTemp { get; set; }
public byte[] Recived { get; set; }
+
+ public string RequestId { get; set; }
}
}
diff --git a/FastTunnel.Core/Server/BufferManeger.cs b/FastTunnel.Core/Server/BufferManeger.cs
index cc20bf5..e95bc8c 100644
--- a/FastTunnel.Core/Server/BufferManeger.cs
+++ b/FastTunnel.Core/Server/BufferManeger.cs
@@ -40,7 +40,6 @@ namespace FastTunnel.Core.Server
// true if the buffer was successfully set, else false
public bool SetBuffer(SocketAsyncEventArgs args)
{
-
if (m_freeIndexPool.Count > 0)
{
args.SetBuffer(m_buffer, m_freeIndexPool.Pop(), m_bufferSize);
@@ -51,6 +50,7 @@ namespace FastTunnel.Core.Server
{
return false;
}
+
args.SetBuffer(m_buffer, m_currentIndex, m_bufferSize);
m_currentIndex += m_bufferSize;
}
diff --git a/FastTunnel.Core/Server/PipeHepler.cs b/FastTunnel.Core/Server/PipeHepler.cs
index c4e2bc8..7114bcd 100644
--- a/FastTunnel.Core/Server/PipeHepler.cs
+++ b/FastTunnel.Core/Server/PipeHepler.cs
@@ -13,6 +13,7 @@ namespace FastTunnel.Core.Server
{
Socket m_socket;
Func processLine;
+ const int minimumBufferSize = 512;
public PipeHepler(Socket socket, Func processLine)
{
@@ -30,8 +31,6 @@ namespace FastTunnel.Core.Server
private async Task FillPipeAsync(PipeWriter writer)
{
- const int minimumBufferSize = 512;
-
while (true)
{
// Allocate at least 512 bytes from the PipeWriter.
@@ -77,7 +76,7 @@ namespace FastTunnel.Core.Server
if (!processLine(m_socket, line.ToArray()))
{
// 停止继续监听
-
+ break;
}
}
diff --git a/FastTunnel.Core/Server/Server.cs b/FastTunnel.Core/Server/Server.cs
index 68d3188..bb6add7 100644
--- a/FastTunnel.Core/Server/Server.cs
+++ b/FastTunnel.Core/Server/Server.cs
@@ -3,6 +3,8 @@
// is sent back to the client. The read and echo back to the client pattern
// is continued until the client disconnects.
using FastTunnel.Core.Extensions;
+using FastTunnel.Core.Utility.Extensions;
+using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Net;
@@ -28,6 +30,9 @@ namespace FastTunnel.Core.Server
Func m_handller;
string m_sectionFlag;
+ IPEndPoint _localEndPoint;
+
+ ILogger _logger;
// Create an uninitialized server instance.
// To start the server listening for connection requests
@@ -35,8 +40,9 @@ namespace FastTunnel.Core.Server
//
// the maximum number of connections the sample is designed to handle simultaneously
// buffer size to use for each socket I/O operation
- public Server(int numConnections, int receiveBufferSize)
+ public Server(int numConnections, int receiveBufferSize, ILogger logger)
{
+ _logger = logger;
//m_totalBytesRead = 0;
m_numConnectedSockets = 0;
m_numConnections = numConnections;
@@ -47,6 +53,7 @@ namespace FastTunnel.Core.Server
receiveBufferSize);
m_readWritePool = new SocketAsyncEventArgsPool(numConnections);
+
m_maxNumberAcceptedClients = new Semaphore(numConnections, numConnections);
}
@@ -88,12 +95,13 @@ namespace FastTunnel.Core.Server
{
m_handller = handller;
m_sectionFlag = sectionFlag;
+ _localEndPoint = localEndPoint;
// create the socket which listens for incoming connections
listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(localEndPoint);
// start the server with a listen backlog of 100 connections
- listenSocket.Listen(100);
+ listenSocket.Listen();
// post accepts on the listening socket
StartAccept(null);
@@ -117,6 +125,7 @@ namespace FastTunnel.Core.Server
}
m_maxNumberAcceptedClients.WaitOne();
+
bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg);
if (!willRaiseEvent)
{
@@ -126,7 +135,6 @@ namespace FastTunnel.Core.Server
// This method is the callback method associated with Socket.AcceptAsync
// operations and is invoked when an accept operation is complete
- //
void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
ProcessAccept(e);
@@ -135,15 +143,19 @@ namespace FastTunnel.Core.Server
private void ProcessAccept(SocketAsyncEventArgs e)
{
Interlocked.Increment(ref m_numConnectedSockets);
+ _logger.LogInformation($"[当前连接数]:{_localEndPoint.Port} | {m_numConnectedSockets}");
// Get the socket for the accepted client connection and put it into the
//ReadEventArg object user token
SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop();
- ((AsyncUserToken)readEventArgs.UserToken).Socket = e.AcceptSocket;
- ((AsyncUserToken)readEventArgs.UserToken).MassgeTemp = null;
- ((AsyncUserToken)readEventArgs.UserToken).Recived = null;
+ var token = readEventArgs.UserToken as AsyncUserToken;
+ token.Socket = e.AcceptSocket;
+ token.MassgeTemp = null;
+ token.Recived = null;
+ token.RequestId = $"{DateTime.Now.GetChinaTicks()}_{Guid.NewGuid().ToString().Replace("-", string.Empty)}";
+
+ _logger.LogDebug($"Accept {token.RequestId}");
- Console.WriteLine("ReceiveAsync");
// As soon as the client is connected, post a receive to the connection
bool willRaiseEvent = e.AcceptSocket.ReceiveAsync(readEventArgs);
if (!willRaiseEvent)
@@ -181,10 +193,11 @@ namespace FastTunnel.Core.Server
private void ProcessReceive(SocketAsyncEventArgs e)
{
AsyncUserToken token = (AsyncUserToken)e.UserToken;
+ _logger.LogDebug($"[ProcessReceive]: {_localEndPoint.Port} | {token.RequestId}");
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
{
- //increment the count of the total bytes receive by the server
- //Interlocked.Add(ref m_totalBytesRead, e.BytesTransferred);
+ // increment the count of the total bytes receive by the server
+ // Interlocked.Add(ref m_totalBytesRead, e.BytesTransferred);
if (token.Recived != null)
{
byte[] resArr = new byte[token.Recived.Length + e.BytesTransferred];
@@ -292,6 +305,7 @@ namespace FastTunnel.Core.Server
// decrement the counter keeping track of the total number of clients connected to the server
Interlocked.Decrement(ref m_numConnectedSockets);
+ _logger.LogInformation($"[SocketCount]:{_localEndPoint.Port} | {m_numConnectedSockets}");
// Free the SocketAsyncEventArg so they can be reused by another client
m_readWritePool.Push(e);
diff --git a/FastTunnel.Core/Services/ServiceFastTunnelClient.cs b/FastTunnel.Core/Services/ServiceFastTunnelClient.cs
index 36995e2..738f934 100644
--- a/FastTunnel.Core/Services/ServiceFastTunnelClient.cs
+++ b/FastTunnel.Core/Services/ServiceFastTunnelClient.cs
@@ -41,7 +41,6 @@ namespace FastTunnel.Core.Services
return Task.CompletedTask;
}
-
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
try
diff --git a/FastTunnel.Core/Sockets/AsyncSocketSwap.cs b/FastTunnel.Core/Sockets/AsyncSocketSwap.cs
index 0d5d10b..7ee817f 100644
--- a/FastTunnel.Core/Sockets/AsyncSocketSwap.cs
+++ b/FastTunnel.Core/Sockets/AsyncSocketSwap.cs
@@ -93,7 +93,6 @@ namespace FastTunnel.Core.Sockets
var token = e.UserToken as SwapUserToken;
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
{
- Console.WriteLine("ProcessReceive:" + e.BytesTransferred);
e.SetBuffer(e.Offset, 512);
if (!token.Sender.SendAsync(e))
{
diff --git a/FastTunnel.Core/Sockets/ConnectSocket.cs b/FastTunnel.Core/Sockets/ConnectSocket.cs
new file mode 100644
index 0000000..6d26258
--- /dev/null
+++ b/FastTunnel.Core/Sockets/ConnectSocket.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FastTunnel.Core.Sockets
+{
+ public class ConnectSocket
+ {
+ string m_server;
+ int m_port;
+
+ public ConnectSocket(string server, int port)
+ {
+ this.m_port = port;
+ this.m_server = server;
+ }
+
+ public Socket Connect()
+ {
+ Socket s = null;
+ IPHostEntry hostEntry = null;
+
+ // Get host related information.
+ hostEntry = Dns.GetHostEntry(m_server);
+
+ // Loop through the AddressList to obtain the supported AddressFamily. This is to avoid
+ // an exception that occurs when the host IP Address is not compatible with the address family
+ // (typical in the IPv6 case).
+ foreach (IPAddress address in hostEntry.AddressList)
+ {
+ IPEndPoint ipe = new IPEndPoint(address, m_port);
+ Socket tempSocket =
+ new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+
+ tempSocket.Connect(ipe);
+
+ if (tempSocket.Connected)
+ {
+ s = tempSocket;
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ return s;
+ }
+ }
+}
diff --git a/FastTunnel.Core/Sockets/SocketSwap.cs b/FastTunnel.Core/Sockets/SocketSwap.cs
index ef22524..48ccf87 100644
--- a/FastTunnel.Core/Sockets/SocketSwap.cs
+++ b/FastTunnel.Core/Sockets/SocketSwap.cs
@@ -1,6 +1,9 @@
using FastTunnel.Core.Dispatchers;
+using FastTunnel.Core.Utility.Extensions;
+using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Net.Sockets;
using System.Text;
using System.Threading;
@@ -9,9 +12,12 @@ namespace FastTunnel.Core.Sockets
{
public class SocketSwap : ISocketSwap
{
- private Socket _sockt1;
- private Socket _sockt2;
- bool Swaped = false;
+ private readonly Socket m_sockt1;
+ private readonly Socket m_sockt2;
+ private readonly string m_msgId = null;
+ private readonly ILogger m_logger;
+
+ private bool Swaped = false;
private class Channel
{
@@ -20,100 +26,116 @@ namespace FastTunnel.Core.Sockets
public Socket Receive { get; set; }
}
- public SocketSwap(Socket sockt1, Socket sockt2)
+ public SocketSwap(Socket sockt1, Socket sockt2, ILogger logger, string msgId)
{
- _sockt1 = sockt1;
- _sockt2 = sockt2;
+ m_sockt1 = sockt1;
+ m_sockt2 = sockt2;
+ m_msgId = msgId;
+ m_logger = logger;
}
public void StartSwap()
{
+ m_logger?.LogDebug($"StartSwap {m_msgId}");
+
Swaped = true;
ThreadPool.QueueUserWorkItem(swapCallback, new Channel
{
- Send = _sockt1,
- Receive = _sockt2
+ Send = m_sockt1,
+ Receive = m_sockt2
});
ThreadPool.QueueUserWorkItem(swapCallback, new Channel
{
- Send = _sockt2,
- Receive = _sockt1
+ Send = m_sockt2,
+ Receive = m_sockt1
});
}
private void swapCallback(object state)
{
+ m_logger?.LogDebug($"swapCallback {m_msgId}");
var chanel = state as Channel;
- byte[] result = new byte[1024];
+ byte[] result = new byte[512];
while (true)
{
+ int num;
+
try
{
- if (!chanel.Receive.Connected)
+ try
+ {
+ num = chanel.Receive.Receive(result, result.Length, SocketFlags.None);
+ }
+ catch (Exception)
+ {
+ closeSocket("Revice Fail");
break;
- int num = chanel.Receive.Receive(result, result.Length, SocketFlags.None);
+ }
if (num == 0)
{
- chanel.Receive.Close();
-
- try
- {
- // Release the socket.//
- chanel.Send.Shutdown(SocketShutdown.Both);
- }
- catch { }
- finally
- {
- chanel.Send.Close();
- }
+ closeSocket("Normal Close");
break;
}
- if (!chanel.Send.Connected)
- break;
-
- // var str = Encoding.UTF8.GetString(result, 0, num);
-
- chanel.Send.Send(result, num, SocketFlags.None);
- }
- catch (SocketException)
- {
- // Interrupted function call. 10004
- // An existing connection was forcibly closed by the remote host. 10054
- try
- {
- chanel.Send.Shutdown(SocketShutdown.Both);
- }
- catch { }
- finally
- {
- chanel.Send.Close();
- }
-
try
{
- chanel.Receive.Shutdown(SocketShutdown.Both);
+ chanel.Send.Send(result, num, SocketFlags.None);
}
- catch { }
- finally
+ catch (Exception)
{
- chanel.Receive.Close();
+ closeSocket("Send Fail");
+ break;
}
- break;
}
catch (Exception ex)
{
- Console.Write(ex.ToString());
- throw;
+ m_logger.LogCritical(ex, "致命异常");
+ break;
}
}
+
+ var interval = long.Parse(DateTime.Now.GetChinaTicks()) - long.Parse(m_msgId.Split('_')[0]);
+ m_logger?.LogDebug($"endSwap {m_msgId} 交互时常:{interval}ms");
+ }
+
+ private void closeSocket(string msg)
+ {
+ m_logger.LogDebug($"【closeSocket】:{msg}");
+
+ try
+ {
+ m_sockt1.Shutdown(SocketShutdown.Both);
+ }
+ catch (Exception)
+ {
+ }
+ finally
+ {
+ m_sockt1.Close();
+ }
+
+ try
+ {
+ m_sockt2.Shutdown(SocketShutdown.Both);
+
+ }
+ catch (Exception)
+ {
+ }
+ finally
+ {
+ m_sockt2.Close();
+ }
+
}
public ISocketSwap BeforeSwap(Action fun)
{
+ m_logger?.LogDebug($"BeforeSwap {m_msgId}");
+
if (Swaped)
{
throw new Exception("BeforeSwap must be invoked before StartSwap!");
diff --git a/FastTunnel.Core/Utility/Extensions/DateTimeExtensions.cs b/FastTunnel.Core/Utility/Extensions/DateTimeExtensions.cs
new file mode 100644
index 0000000..5ea7f58
--- /dev/null
+++ b/FastTunnel.Core/Utility/Extensions/DateTimeExtensions.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FastTunnel.Core.Utility.Extensions
+{
+ public static class DateTimeExtensions
+ {
+ public static string GetChinaTicks(this DateTime dateTime)
+ {
+ // 北京时间相差8小时
+ DateTime startTime = TimeZoneInfo.ConvertTime(new DateTime(1970, 1, 1, 8, 0, 0, 0), TimeZoneInfo.Local);
+ long t = (dateTime.Ticks - startTime.Ticks) / 10000;
+ return t.ToString();
+ }
+ }
+}
diff --git a/addhost.bat b/addhost.bat
index e296c31..b8a76c8 100644
--- a/addhost.bat
+++ b/addhost.bat
@@ -2,8 +2,8 @@
echo 127.0.0.1 test.cc >>C:\Windows\System32\drivers\etc\hosts
echo 127.0.0.1 test.test.cc >>C:\Windows\System32\drivers\etc\hosts
echo 127.0.0.1 test1.test.cc >>C:\Windows\System32\drivers\etc\hosts
-echo 127.0.0.1 test111.test.cc >>C:\Windows\System32\drivers\etc\hosts
-echo 127.0.0.1 test111.test.cc >>C:\Windows\System32\drivers\etc\hosts
+echo 127.0.0.1 test2.test.cc >>C:\Windows\System32\drivers\etc\hosts
+echo 127.0.0.1 test3.test.cc >>C:\Windows\System32\drivers\etc\hosts
echo 127.0.0.1 www.abc.com >>C:\Windows\System32\drivers\etc\hosts
pause
\ No newline at end of file