mirror of
https://github.com/FastTunnel/FastTunnel.git
synced 2025-02-08 02:39:29 +08:00
性能优化
This commit is contained in:
parent
460682dde5
commit
3a7c5d4512
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
/// <see cref="https://docs.microsoft.com/zh-cn/windows/win32/winsock/windows-sockets-error-codes-2"/>
|
||||
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<Message<JObject>>(words);
|
||||
if (Msg.MessageType!= MessageType.Heart)
|
||||
{
|
||||
_logger.LogDebug($"HandleServerRequest {words}");
|
||||
}
|
||||
|
||||
IClientHandler handler;
|
||||
switch (Msg.MessageType)
|
||||
{
|
||||
|
|
|
@ -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<NewCustomerMassage> { 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<NewCustomerMassage> { 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 _);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<RepositoryType>git</RepositoryType>
|
||||
<PackageTags>FastTunnel.Core</PackageTags>
|
||||
<PackageReleaseNotes>FastTunnel.Core</PackageReleaseNotes>
|
||||
<Version>1.1.2</Version>
|
||||
<Version>1.1.3</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -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<HttpRequestHandler> _logger;
|
||||
|
||||
public HttpRequestHandler(ILogger<HttpRequestHandler> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void HandlerMsg(FastTunnelClient cleint, Message<JObject> Msg)
|
||||
{
|
||||
var request = Msg.Content.ToObject<NewCustomerMassage>();
|
||||
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<SwapMassage> { 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<NewSSHHandler> _logger;
|
||||
public NewSSHHandler(ILogger<NewSSHHandler> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void HandlerMsg(FastTunnelClient cleint, Message<JObject> Msg)
|
||||
{
|
||||
var request_ssh = Msg.Content.ToObject<NewSSHRequest>();
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,10 +28,14 @@ namespace FastTunnel.Core.Handlers.Server
|
|||
var SwapMsg = msg.Content.ToObject<SwapMassage>();
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -14,5 +14,7 @@ namespace FastTunnel.Core.Server
|
|||
public string MassgeTemp { get; set; }
|
||||
|
||||
public byte[] Recived { get; set; }
|
||||
|
||||
public string RequestId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ namespace FastTunnel.Core.Server
|
|||
// <returns>true if the buffer was successfully set, else false</returns>
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace FastTunnel.Core.Server
|
|||
{
|
||||
Socket m_socket;
|
||||
Func<Socket, byte[], bool> processLine;
|
||||
const int minimumBufferSize = 512;
|
||||
|
||||
public PipeHepler(Socket socket, Func<Socket, byte[], bool> 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<AsyncUserToken, string, bool> 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
|
|||
//
|
||||
// <param name="numConnections">the maximum number of connections the sample is designed to handle simultaneously</param>
|
||||
// <param name="receiveBufferSize">buffer size to use for each socket I/O operation</param>
|
||||
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);
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ namespace FastTunnel.Core.Services
|
|||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
try
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
55
FastTunnel.Core/Sockets/ConnectSocket.cs
Normal file
55
FastTunnel.Core/Sockets/ConnectSocket.cs
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
|
|
19
FastTunnel.Core/Utility/Extensions/DateTimeExtensions.cs
Normal file
19
FastTunnel.Core/Utility/Extensions/DateTimeExtensions.cs
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue
Block a user