Compare commits
2 Commits
fc1195c446
...
a9bc8c4e7d
| Author | SHA1 | Date | |
|---|---|---|---|
| a9bc8c4e7d | |||
| cdda6c0c8a |
@ -44,9 +44,11 @@
|
||||
<Compile Include="Attributes\PacketIgnore.cs" />
|
||||
<Compile Include="Client.cs" />
|
||||
<Compile Include="Events\ClientConnectedEventArgs.cs" />
|
||||
<Compile Include="Events\DataReceivedEventArgs.cs" />
|
||||
<Compile Include="Interfaces\IManager.cs" />
|
||||
<Compile Include="Interfaces\IPacket.cs" />
|
||||
<Compile Include="Managers\PacketManager.cs" />
|
||||
<Compile Include="Packets\Packet.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Server.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Articulate_Network.Attributes
|
||||
{
|
||||
public class PacketIgnore : System.Attribute
|
||||
public class PacketIgnore : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
133
Client.cs
133
Client.cs
@ -1,9 +1,14 @@
|
||||
using Articulate_Network.Interfaces;
|
||||
using Articulate_Network.Managers;
|
||||
using Articulate_Network.Packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -12,12 +17,19 @@ namespace Articulate_Network
|
||||
public class Client
|
||||
{
|
||||
List<IManager> managers = new List<IManager>();
|
||||
int bufferSize = 16384;
|
||||
|
||||
TcpClient tcp;
|
||||
|
||||
public Client()
|
||||
{
|
||||
tcp = new TcpClient();
|
||||
InitializeManagers();
|
||||
|
||||
tcp = new TcpClient()
|
||||
{
|
||||
SendBufferSize = bufferSize,
|
||||
ReceiveBufferSize = bufferSize
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<TcpClient> Connect(string ip, int port)
|
||||
@ -28,6 +40,11 @@ namespace Articulate_Network
|
||||
{
|
||||
tcp.Connect(ip, port);
|
||||
|
||||
tcp.SendBufferSize = bufferSize;
|
||||
tcp.ReceiveBufferSize = bufferSize;
|
||||
|
||||
_ = ReceiveData();
|
||||
|
||||
return tcp;
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -39,9 +56,121 @@ namespace Articulate_Network
|
||||
);
|
||||
}
|
||||
|
||||
public async Task<bool> SendPacket(IPacket packet)
|
||||
public async Task<bool> SendPacket(Packet packet)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
byte[] buffer = Get<PacketManager>().SerializePacket(packet);
|
||||
|
||||
tcp.Client.Send(buffer, buffer.Length, SocketFlags.None);
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> ReceiveData()
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
byte[] buffer = new byte[bufferSize];
|
||||
|
||||
int offset = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
int bytesToRead = tcp.Client.Receive(buffer, offset, buffer.Length - offset, SocketFlags.None);
|
||||
|
||||
//Console.WriteLine("Bytes to read: " + bytesToRead);
|
||||
|
||||
var ms = new MemoryStream(buffer, 0, bytesToRead);
|
||||
var br = new BinaryReader(ms);
|
||||
|
||||
while (ms.Position < ms.Length)
|
||||
{
|
||||
int length = (int)br.ReadInt64();
|
||||
|
||||
OnDataReceived(new Articulate_Network.Events.DataReceivedEventArgs()
|
||||
{
|
||||
Packet = Get<PacketManager>().DeserializePacket(ms)
|
||||
});
|
||||
|
||||
int end = (int)br.ReadInt64();
|
||||
|
||||
bool endOfPacket = end == length;
|
||||
|
||||
if (endOfPacket && ms.Position < ms.Length)
|
||||
{
|
||||
int nextPacketSize = (int)br.ReadInt64();
|
||||
|
||||
ms.Position -= 8;
|
||||
|
||||
Console.WriteLine("Next size: " + nextPacketSize);
|
||||
|
||||
offset = (int)(ms.Length - ms.Position);
|
||||
|
||||
buffer = new byte[bufferSize];
|
||||
|
||||
ms.Read(buffer, 0, offset);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//Console.WriteLine(ms.Position);
|
||||
|
||||
/*if (ms.Position + length > ms.Length)
|
||||
{
|
||||
Console.WriteLine("Bytes to read: " + bytesToRead);
|
||||
Console.WriteLine("Memory length: " + ms.Length);
|
||||
Console.WriteLine("Memory Pos: " + ms.Position);
|
||||
Console.WriteLine("Length: " + length);
|
||||
ms.Position -= 8;
|
||||
|
||||
buffer = new byte[bufferSize];
|
||||
|
||||
ms.Read(buffer, 0, offset);
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void InitializeManagers()
|
||||
{
|
||||
var @interface = typeof(IManager);
|
||||
|
||||
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
var managersFound = assembly.GetTypes().Where(t => @interface.IsAssignableFrom(t) && !t.IsAbstract);
|
||||
|
||||
foreach (var m in managersFound)
|
||||
{
|
||||
var manager = (IManager)Activator.CreateInstance(m);
|
||||
|
||||
manager.Initialize();
|
||||
|
||||
managers.Add(manager);
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"Initialized {managers.Count} manager{(managers.Count > 1 ? "s" : "")}");
|
||||
}
|
||||
|
||||
public T Get<T>()
|
||||
{
|
||||
return (T)managers.SingleOrDefault(t => typeof(T) == t.GetType());
|
||||
}
|
||||
|
||||
protected virtual void OnDataReceived(Articulate_Network.Events.DataReceivedEventArgs e)
|
||||
{
|
||||
EventHandler<Articulate_Network.Events.DataReceivedEventArgs> handler = DataReceived;
|
||||
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<Articulate_Network.Events.DataReceivedEventArgs> DataReceived;
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Articulate_Network.Events
|
||||
{
|
||||
public class ClientConnectedEventArgs
|
||||
public class ClientConnectedEventArgs : EventArgs
|
||||
{
|
||||
public TcpClient TcpClient { get; set; }
|
||||
}
|
||||
|
||||
16
Events/DataReceivedEventArgs.cs
Normal file
16
Events/DataReceivedEventArgs.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using Articulate_Network.Packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Articulate_Network.Events
|
||||
{
|
||||
public class DataReceivedEventArgs : EventArgs
|
||||
{
|
||||
public TcpClient Client { get; set; }
|
||||
public Packet Packet { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
using Articulate_Network.Attributes;
|
||||
using Articulate_Network.Interfaces;
|
||||
using Articulate_Network.Packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@ -14,7 +15,7 @@ namespace Articulate_Network.Managers
|
||||
public class PacketManager : IManager
|
||||
{
|
||||
Dictionary<Type, List<PropertyInfo>> packetInfo = new Dictionary<Type, List<PropertyInfo>>();
|
||||
Dictionary<Type, IPacket> packetInstances = new Dictionary<Type, IPacket>();
|
||||
Dictionary<string, Packet> packetInstances = new Dictionary<string, Packet>();
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
@ -22,13 +23,13 @@ namespace Articulate_Network.Managers
|
||||
|
||||
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
var managersFound = assembly.GetTypes().Where(t => @interface.IsAssignableFrom(t) && !t.IsAbstract);
|
||||
var packetsFound = assembly.GetTypes().Where(t => @interface.IsAssignableFrom(t) && !t.IsAbstract);
|
||||
|
||||
foreach (var p in managersFound)
|
||||
foreach (var p in packetsFound)
|
||||
{
|
||||
var packet = (IPacket)Activator.CreateInstance(p);
|
||||
var packet = (Packet)Activator.CreateInstance(p);
|
||||
|
||||
packetInstances.Add(p, packet);
|
||||
packetInstances.Add(p.Name, packet);
|
||||
LoadPacketInfo(packet);
|
||||
}
|
||||
}
|
||||
@ -41,7 +42,7 @@ namespace Articulate_Network.Managers
|
||||
packetInfo.Add(packet.GetType(), packet.GetType().GetProperties().Where(f => !Attribute.IsDefined(f, typeof(PacketIgnore))).OrderBy(f => f.Name).ToList());
|
||||
}
|
||||
|
||||
public T Send<T>(IPacket packet)
|
||||
public void Send(Packet packet)
|
||||
{
|
||||
Stopwatch watch = new Stopwatch();
|
||||
watch.Start();
|
||||
@ -57,19 +58,24 @@ namespace Articulate_Network.Managers
|
||||
|
||||
var serialized = SerializePacket(packet);
|
||||
|
||||
var deserialized = DeserializePacket<T>(serialized);
|
||||
//var deserialized = DeserializePacket<T>(serialized);
|
||||
|
||||
return (T)deserialized;
|
||||
//return (T)deserialized;
|
||||
}
|
||||
|
||||
public MemoryStream SerializePacket(IPacket packet)
|
||||
public byte[] SerializePacket(Packet packet)
|
||||
{
|
||||
if (!packetInfo.ContainsKey(packet.GetType()))
|
||||
LoadPacketInfo(packet);
|
||||
|
||||
Stopwatch watch = new Stopwatch();
|
||||
watch.Start();
|
||||
var fields = packetInfo[packet.GetType()];
|
||||
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
|
||||
MemoryStream buffer = new MemoryStream();
|
||||
BinaryWriter binaryWriter = new BinaryWriter(buffer);
|
||||
|
||||
binaryWriter.Write(packet.GetType().Name);
|
||||
|
||||
foreach (var field in fields)
|
||||
{
|
||||
@ -79,27 +85,57 @@ namespace Articulate_Network.Managers
|
||||
if (field.PropertyType == typeof(int))
|
||||
binaryWriter.Write((int)field.GetValue(packet));
|
||||
|
||||
if (field.PropertyType == typeof(long))
|
||||
binaryWriter.Write((long)field.GetValue(packet));
|
||||
|
||||
if (field.PropertyType == typeof(string))
|
||||
binaryWriter.Write((string)field.GetValue(packet));
|
||||
binaryWriter.Write(((string)field.GetValue(packet)) ?? string.Empty);
|
||||
|
||||
if (field.PropertyType.IsEnum)
|
||||
binaryWriter.Write((int)field.GetValue(packet));
|
||||
|
||||
if (field.PropertyType == typeof(byte[]))
|
||||
{
|
||||
byte[] buf = (byte[])field.GetValue(packet);
|
||||
binaryWriter.Write(buf.Length);
|
||||
binaryWriter.Write(buf);
|
||||
}
|
||||
|
||||
memoryStream.Position = 0;
|
||||
//Console.WriteLine(field.Name);
|
||||
}
|
||||
|
||||
long length = buffer.Length;
|
||||
byte[] packetData = buffer.ToArray();
|
||||
|
||||
buffer.SetLength(0);
|
||||
|
||||
binaryWriter.Write(length);
|
||||
binaryWriter.Write(packetData);
|
||||
binaryWriter.Write(length);
|
||||
|
||||
watch.Stop();
|
||||
|
||||
Console.WriteLine($"Serialize time: {watch.ElapsedTicks / 10} microseconds");
|
||||
return memoryStream;
|
||||
//Console.WriteLine($"Serialize time: {watch.ElapsedTicks / 10} microseconds");
|
||||
return buffer.ToArray();
|
||||
}
|
||||
|
||||
public T DeserializePacket<T>(Stream stream)
|
||||
public Packet DeserializePacket(MemoryStream stream)
|
||||
{
|
||||
Stopwatch watch = new Stopwatch();
|
||||
watch.Start();
|
||||
IPacket packet = /*packetInstances[typeof(T)];*/(IPacket)Activator.CreateInstance(typeof(T));
|
||||
|
||||
var fields = packetInfo[typeof(T)];
|
||||
BinaryReader reader = new BinaryReader(stream);
|
||||
|
||||
string typeName = reader.ReadString();
|
||||
|
||||
Console.WriteLine(typeName);
|
||||
|
||||
Packet packet = packetInstances[typeName];/*(IPacket)Activator.CreateInstance(typeof(T));*/
|
||||
|
||||
var fields = packetInfo[packet.GetType()];
|
||||
|
||||
//Console.WriteLine($"Stream length: {stream.Length}");
|
||||
//Console.WriteLine($"Stream position: {stream.Position}");
|
||||
|
||||
foreach (var field in fields)
|
||||
{
|
||||
if (field.PropertyType == typeof(bool))
|
||||
@ -108,15 +144,37 @@ namespace Articulate_Network.Managers
|
||||
if (field.PropertyType == typeof(int))
|
||||
field.SetValue(packet, reader.ReadInt32());
|
||||
|
||||
if (field.PropertyType == typeof(long))
|
||||
field.SetValue(packet, reader.ReadInt64());
|
||||
|
||||
if (field.PropertyType == typeof(string))
|
||||
field.SetValue(packet, reader.ReadString());
|
||||
|
||||
if (field.PropertyType.IsEnum)
|
||||
field.SetValue(packet, reader.ReadInt32());
|
||||
|
||||
if (field.PropertyType == typeof(byte[]))
|
||||
{
|
||||
int length = reader.ReadInt32();
|
||||
field.SetValue(packet, reader.ReadBytes(length));
|
||||
}
|
||||
}
|
||||
|
||||
watch.Stop();
|
||||
|
||||
Console.WriteLine($"Deserialize time: {watch.ElapsedTicks / 10} microseconds");
|
||||
//Console.WriteLine($"Deserialize time: {watch.ElapsedTicks / 10} microseconds");
|
||||
|
||||
return (T)packet;
|
||||
return packet;
|
||||
}
|
||||
|
||||
public Packet DeserializePacket(byte[] bytes)
|
||||
{
|
||||
return DeserializePacket(new MemoryStream(bytes));
|
||||
}
|
||||
|
||||
public void HandlePacket(Packet packet)
|
||||
{
|
||||
Console.WriteLine(packet.GetType().Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
Packets/Packet.cs
Normal file
14
Packets/Packet.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using Articulate_Network.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Articulate_Network.Packets
|
||||
{
|
||||
public abstract class Packet : IPacket
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
84
Server.cs
84
Server.cs
@ -1,8 +1,10 @@
|
||||
using Articulate_Network.Events;
|
||||
using Articulate_Network.Interfaces;
|
||||
using Articulate_Network.Managers;
|
||||
using Articulate_Network.Packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
@ -15,15 +17,13 @@ namespace Articulate_Network
|
||||
public class Server
|
||||
{
|
||||
List<IManager> managers = new List<IManager>();
|
||||
List<TcpClient> clients = new List<TcpClient>();
|
||||
TcpClient[] clients = new TcpClient[300];
|
||||
|
||||
TcpListener tcpListener;
|
||||
|
||||
public Server()
|
||||
{
|
||||
InitializeManagers();
|
||||
|
||||
Console.WriteLine($"Initialized {managers.Count} manager{(managers.Count > 1 ? "s" : "")}");
|
||||
}
|
||||
|
||||
public async Task<bool> Start(string ip, int port)
|
||||
@ -57,16 +57,74 @@ namespace Articulate_Network
|
||||
{
|
||||
var client = await tcpListener.AcceptTcpClientAsync();
|
||||
|
||||
clients.Add(client);
|
||||
for (int i = 0; i < clients.Length; i++)
|
||||
if (clients[i] == null)
|
||||
{
|
||||
clients[i] = client;
|
||||
Console.WriteLine($"Client {i+1} connected from {(client.Client.RemoteEndPoint as IPEndPoint).Address}.");
|
||||
break;
|
||||
}
|
||||
|
||||
_ = ReceiveData(client);
|
||||
|
||||
OnClientConnected(new ClientConnectedEventArgs() { TcpClient = client });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<bool> SendPacket(IPacket packet)
|
||||
public async Task<bool> ReceiveData(TcpClient client)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
byte[] buffer = new byte[8192];
|
||||
var ms = new MemoryStream(buffer);
|
||||
var br = new BinaryReader(ms);
|
||||
|
||||
while (client.Connected)
|
||||
{
|
||||
try
|
||||
{
|
||||
int bytesToRead = client.Client.Receive(buffer, buffer.Length, SocketFlags.None);
|
||||
|
||||
ms.Position = 0;
|
||||
|
||||
while (ms.Position < bytesToRead)
|
||||
{
|
||||
int length = (int)br.ReadInt64();
|
||||
|
||||
OnDataReceived(new Articulate_Network.Events.DataReceivedEventArgs()
|
||||
{
|
||||
Packet = Get<PacketManager>().DeserializePacket(ms),
|
||||
Client = client
|
||||
});
|
||||
|
||||
int end = (int)br.ReadInt64();
|
||||
}
|
||||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
for (int i = 0; i < clients.Length; i++)
|
||||
if (clients[i] == client)
|
||||
{
|
||||
clients[i] = null;
|
||||
Console.WriteLine($"Client {i+1} lost connection.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> SendPacket(TcpClient tcpClient, Packet packet)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
byte[] buffer = Get<PacketManager>().SerializePacket(packet);
|
||||
|
||||
tcpClient.Client.Send(buffer, buffer.Length, SocketFlags.None);
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -87,6 +145,8 @@ namespace Articulate_Network
|
||||
managers.Add(manager);
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"Initialized {managers.Count} manager{(managers.Count > 1 ? "s" : "")}");
|
||||
}
|
||||
|
||||
public T Get<T>()
|
||||
@ -103,5 +163,15 @@ namespace Articulate_Network
|
||||
}
|
||||
|
||||
public event EventHandler<ClientConnectedEventArgs> ClientConnected;
|
||||
|
||||
protected virtual void OnDataReceived(Articulate_Network.Events.DataReceivedEventArgs e)
|
||||
{
|
||||
EventHandler<Articulate_Network.Events.DataReceivedEventArgs> handler = DataReceived;
|
||||
|
||||
if (handler != null)
|
||||
handler(this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<Articulate_Network.Events.DataReceivedEventArgs> DataReceived;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user