Skip to content

Commit

Permalink
完成端口复用功能
Browse files Browse the repository at this point in the history
  • Loading branch information
tmoonlight committed Feb 13, 2019
1 parent a827c82 commit 135a40c
Show file tree
Hide file tree
Showing 13 changed files with 302 additions and 305 deletions.
14 changes: 14 additions & 0 deletions NSmartProxy/NSmartProxy.Client/ClientAppWorker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;

namespace NSmartProxy
{
public class ClientAppWorker
{
public List<TcpClient> TcpClientGroup = new List<TcpClient>();
public int AppId; //1~255
public int Port; //0~65535
}
}
16 changes: 9 additions & 7 deletions NSmartProxy/NSmartProxy.Client/ClientRouter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public class ClientRouter
CancellationTokenSource CANCELTOKEN = new CancellationTokenSource();
CancellationTokenSource TRANSFERING_TOKEN = new CancellationTokenSource();
ServerConnnectionManager ConnnectionManager;

public Dictionary<int, int> AppPortMap; //key:appid,value:servicetargetport 目标端口

/// <summary>
/// 重要:连接服务端
/// </summary>
Expand All @@ -39,20 +40,21 @@ private void ServerConnnectionManager_ClientGroupConnected(object sender, EventA
{

Console.WriteLine("开启连接");
OpenTrasferation(providerClient);
OpenTrasferation(args.App.AppId, providerClient);
}

}

private async Task OpenTrasferation(TcpClient providerClient)
private async Task OpenTrasferation(int appId, TcpClient providerClient)
{
byte[] buffer = new byte[4096];
var providerClientStream = providerClient.GetStream();
int readByteCount = await providerClientStream.ReadAsync(buffer);
//从空闲连接列表中移除
ConnnectionManager.RemoveClient(providerClient);
Console.WriteLine("接受到首条信息");
ConnnectionManager.RemoveClient(appId, providerClient);
Console.WriteLine(appId + "接受到首条信息");
TcpClient toTargetServer = new TcpClient();
//※根据clientid_appid发送到固定的端口※
toTargetServer.Connect(TARGET_SERVICE_ADDRESS, TARGET_SERVICE_ADDRESS_PORT);
NetworkStream targetServerStream = toTargetServer.GetStream();
targetServerStream.Write(buffer, 0, readByteCount);
Expand All @@ -77,14 +79,14 @@ private async Task TcpTransferAsync(NetworkStream providerStream, NetworkStream
}



private async Task<string> StreamTransfer(CancellationToken ct, NetworkStream fromStream, NetworkStream toStream, string signal, Func<byte[], Task<bool>> beforeTransfer = null)
{
await fromStream.CopyToAsync(toStream, ct);
return signal;
}


private async Task<string> ToStaticTransfer(CancellationToken ct, NetworkStream fromStream, NetworkStream toStream, string signal, Func<byte[], Task<bool>> beforeTransfer = null)
{

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\NSmartProxy.Data\NSmartProxy.Data.csproj" />
</ItemGroup>

</Project>
61 changes: 36 additions & 25 deletions NSmartProxy/NSmartProxy.Client/ServerConnnectionManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using NSmartProxy.Client;
using NSmartProxy.Data;
using System;
using System.Collections.Generic;
using System.Net;
Expand All @@ -11,6 +12,7 @@ namespace NSmartProxy
public class ClientGroupEventArgs : EventArgs
{
public IEnumerable<TcpClient> NewClients;
public ClientIdAppId App;
}

public class ServerConnnectionManager
Expand All @@ -23,18 +25,22 @@ private ServerConnnectionManager()
//获取服务端配置信息
//测试 ,暂时设置为3
//int length = Apps.Length
byte[] configBytes = ReadConfigFromProvider();
//要求服务端分配资源并获取服务端配置,待完善
ClientModel clientModel = ReadConfigFromProvider();
//要求服务端分配资源并获取服务端配置,待完善
//Console.WriteLine(config[0] + "!!!!!!!!!");
//唯一的clientid
ClientID = configBytes[0] << 8 + configBytes[1];
this.ClientID = clientModel.ClientId;
//分配appid
ServiceClientListCollection = new Dictionary<int, List<TcpClient>>();
for (int i = 2; i < configBytes.Length; i++)
ServiceClientListCollection = new Dictionary<int, ClientAppWorker>();
for (int i = 0; i < clientModel.AppList.Count; i++)
{
if (configBytes[i] == 0)
break;
ServiceClientListCollection.Add((int)configBytes[i], new List<TcpClient>());
var app = clientModel.AppList[i];
ServiceClientListCollection.Add(clientModel.AppList[i].AppId, new ClientAppWorker()
{
AppId = app.AppId,
Port = app.Port,
TcpClientGroup = new List<TcpClient>(MAX_CONNECT_SIZE)
});
}
//arrangedAppid = configBytes[]

Expand All @@ -45,39 +51,41 @@ private ServerConnnectionManager()
/// 从服务端读取配置
/// </summary>
/// <returns></returns>
private static byte[] ReadConfigFromProvider()
private static ClientModel ReadConfigFromProvider()
{
TcpClient configClient = new TcpClient();
configClient.Connect(ClientRouter.PROVIDER_ADDRESS, ClientRouter.PROVIDER_CONFIG_SERVICE_PORT);
var configStream = configClient.GetStream();
byte[] fourBytes = new byte[4] { 0, 0, 3, 0 };
configStream.Write(fourBytes);

//byte[] fourBytes = new byte[4] { 0, 0, 3, 0 };
configStream.Write(new ClientNewAppRequest { ClientId = 0, ClientCount = 3 }.ToBytes());
byte[] config = new byte[256];
configStream.Read(config);
return config;
int readBytesCount = configStream.Read(config);
return ClientModel.GetFromBytes(config, readBytesCount);
}

public static event EventHandler ClientGroupConnected;
private async Task PollingToProvider()
{
if (ClientID == 0) { Console.WriteLine("error:未连接客户端"); return; };
int hungryNumber = MAX_CONNECT_SIZE / 2;
byte[] clientBytes = StringUtil.IntToBytes(ClientID);
byte[] clientBytes = StringUtil.IntTo2Bytes(ClientID);
//侦听,并且构造连接池
//throw new NotImplementedException();
//int currentClientCount = ServiceClientQueue.Count;
List<Task> taskList = new List<Task>();
foreach (var kv in ServiceClientListCollection)
{
int appid = kv.Key;
byte[] requestBytes = StringUtil.Generate1stRequestBytes(ClientID,appid);
ClientAppWorker app = kv.Value;
byte[] requestBytes = StringUtil.ClientIDAppIdToBytes(ClientID, appid);
taskList.Add(Task.Run(async () =>
{
while (1 == 1)
{

int activeClientCount = 0;
foreach (TcpClient c in ServiceClientListCollection[appid])
foreach (TcpClient c in app.TcpClientGroup)
{
if (c.Connected) activeClientCount++;
}
Expand All @@ -93,10 +101,13 @@ private async Task PollingToProvider()
client.Connect(ClientRouter.PROVIDER_ADDRESS, ClientRouter.PROVIDER_ADDRESS_PORT);
//连完了马上发送端口信息过去,方便服务端分配
client.GetStream().Write(requestBytes);
ServiceClientListCollection[appid].Add(client);
app.TcpClientGroup.Add(client);
clientList.Add(client);
}
ClientGroupConnected(this, new ClientGroupEventArgs() { NewClients = clientList });
ClientGroupConnected(this, new ClientGroupEventArgs() {
NewClients = clientList,
App = new ClientIdAppId { ClientId = ClientID, AppId = appid
} });
}
await Task.Delay(2000);
//currentClientCount = ServiceClientQueue.Count;
Expand All @@ -108,14 +119,14 @@ private async Task PollingToProvider()
Console.WriteLine(resultTask.Exception?.ToString());
}

//可能要改成字典
private Dictionary<int, List<TcpClient>> ServiceClientListCollection;// = new Dictionary<int, List<TcpClient>>();
//key:appid value;ClientApp
private Dictionary<int, ClientAppWorker> ServiceClientListCollection;// = new Dictionary<int, List<TcpClient>>();
private static ServerConnnectionManager Instance = new Lazy<ServerConnnectionManager>(() => new ServerConnnectionManager()).Value;
//Queue<TcpClient> IdleClientsQueue = new Queue<TcpClient>();
public void AddClient(int appId, TcpClient client)
{
ServiceClientListCollection[appId].Add(client);
}
//public void AddClient(int appId, TcpClient client)
//{
// ServiceClientListCollection[appId].Add(client);
//}

public static ServerConnnectionManager GetInstance()
{
Expand All @@ -124,7 +135,7 @@ public static ServerConnnectionManager GetInstance()

public TcpClient RemoveClient(int appId, TcpClient client)
{
if (ServiceClientListCollection[appId].Remove(client))
if (ServiceClientListCollection[appId].TcpClientGroup.Remove(client))

return client;
else
Expand Down
52 changes: 26 additions & 26 deletions NSmartProxy/NSmartProxy.Client/Util/StringUtil.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
using System;
using System.Collections.Generic;
using System.Text;
//using System;
//using System.Collections.Generic;
//using System.Text;

namespace NSmartProxy
{
public class StringUtil
{
public static byte[] IntToBytes(int number)
{
return System.BitConverter.GetBytes(number);
}
//namespace NSmartProxy
//{
// public class StringUtil
// {
// public static byte[] IntTo222Bytes(int number)
// {
// return System.BitConverter.GetBytes(number);
// }

/// <summary>
/// 客户端首次连接服务端时,需要发送标记以便服务端归类
/// </summary>
/// <param name="clientID"></param>
/// <param name="appid"></param>
/// <returns></returns>
public static byte[] Generate1stRequestBytes(int clientID, int appid)
{
byte[] bytes = IntToBytes(clientID);
bytes[2] = (byte)appid;
bytes[3] = 0;
return bytes;
}
}
}
// /// <summary>
// /// 客户端首次连接服务端时,需要发送标记以便服务端归类
// /// </summary>
// /// <param name="clientID"></param>
// /// <param name="appid"></param>
// /// <returns></returns>
// public static byte[] Generate1stRe为questBytes(int clientID, int appid)
// {
// byte[] bytes = IntToBytes(clientID);
// bytes[2] = (byte)appid;
// bytes[3] = 0;
// return bytes;
// }
// }
//}
67 changes: 59 additions & 8 deletions NSmartProxy/NSmartProxy.Data/Model.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace NSmartProxy.Data
{
public class Client
public class ClientModel
{
public int ClientId; //2
public List<App> AppList; //3 * N
Expand All @@ -22,22 +23,26 @@ public byte[] ToBytes()
return listBytes.ToArray();
}

public static Client GetFromBytes(byte[] bytes)
public static ClientModel GetFromBytes(byte[] bytes, int totalLength = 0)
{
Client client = new Client();
client.ClientId = bytes[0] << 8 + bytes[1];
if (totalLength == 0)
{
totalLength = bytes.Length;
}
ClientModel client = new ClientModel();
client.ClientId = (bytes[0] << 8) + bytes[1];
client.AppList = new List<App>();
int appCount = (bytes.Length - 2) / 3;
if (((bytes.Length - 2) % 3) > 0)
int appCount = (totalLength - 2) / 3;
if (((totalLength - 2) % 3) > 0)
{
throw new Exception("error format");
}
for (int i = 2; i < appCount; i++)
for (int i = 0; i < appCount; i++)
{
App app = new App()
{
AppId = bytes[2 + 3 * i],
Port = bytes[3 + 3 * i] << 8 + bytes[4 + 3 * i]
Port = (bytes[3 + 3 * i] << 8) + bytes[4 + 3 * i]
};
client.AppList.Add(app);
}
Expand All @@ -56,6 +61,52 @@ public class ClientIdAppId
{
public int ClientId; //2
public int AppId; //1
public byte[] ToBytes()
{
byte[] bytes = new byte[3];
byte[] clientIdBytres = StringUtil.IntTo2Bytes(ClientId);
bytes[0] = clientIdBytres[0];
bytes[1] = clientIdBytres[1];
bytes[2] = (byte)AppId;
return bytes;
}

public static ClientIdAppId GetFromBytes(byte[] bytes)
{
return new ClientIdAppId
{
ClientId = StringUtil.DoubleBytesToInt(bytes[0], bytes[1]),
AppId = bytes[2]
};
}
}

public class ClientApp
{
public int ClientId;
public int AppId;
public int TargetServicePort;
}

public class ClientNewAppRequest
{
public int ClientId; //2
public int ClientCount; //1
public byte[] ToBytes()
{
byte[] bytes = new byte[3];
byte[] clientIdBytres = StringUtil.IntTo2Bytes(ClientId);
bytes[0] = clientIdBytres[0];
bytes[2] = (byte)ClientCount;
return bytes;
}
public static ClientNewAppRequest GetFromBytes(byte[] bytes)
{
return new ClientNewAppRequest
{
ClientId = StringUtil.DoubleBytesToInt(bytes[0], bytes[1]),
ClientCount = bytes[2]
};
}
}
}
Loading

0 comments on commit 135a40c

Please sign in to comment.