Implementing Packet Framing

Surrounding packets with Int32 6655 to identify packet structure
This commit is contained in:
2021-12-16 16:41:29 +10:00
parent a9bc8c4e7d
commit ece0dffd85
3 changed files with 122 additions and 40 deletions

View File

@ -73,63 +73,67 @@ namespace Articulate_Network
await Task.Run(() => await Task.Run(() =>
{ {
byte[] buffer = new byte[bufferSize]; byte[] buffer = new byte[bufferSize];
int offset = 0; int offset = 0;
while (true) while (true)
{ {
int bytesToRead = tcp.Client.Receive(buffer, offset, buffer.Length - offset, SocketFlags.None); int bytesToRead = tcp.Client.Receive(buffer, offset, buffer.Length - offset, SocketFlags.None);
//Console.WriteLine("Bytes to read: " + bytesToRead); if (offset > 0)
offset = 0;
var ms = new MemoryStream(buffer, 0, bytesToRead); var ms = new MemoryStream(buffer);
var br = new BinaryReader(ms); var br = new BinaryReader(ms);
while (ms.Position < ms.Length) while (ms.Position < ms.Length)
{ {
if (ms.Position + 4 > ms.Length)
break;
int magic = br.ReadInt32();
if (magic != 6655)
{
//Console.WriteLine("Not the start of a packet.");
continue;
}
int length = (int)br.ReadInt64(); int length = (int)br.ReadInt64();
OnDataReceived(new Articulate_Network.Events.DataReceivedEventArgs() if (ms.Position + length > ms.Length) // Received partial packet data, store partial data and continue
{ {
Packet = Get<PacketManager>().DeserializePacket(ms) ms.Position -= 12;
});
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); offset = (int)(ms.Length - ms.Position);
//Console.WriteLine($"Partial data. Offset: {offset}");
buffer = new byte[bufferSize]; buffer = new byte[bufferSize];
ms.Read(buffer, 0, offset); ms.Read(buffer, 0, offset);
break; break;
} }
//Console.WriteLine(ms.Position); ms.Position += length;
int end = (int)br.ReadInt64();
/*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; ms.Position -= 8;
ms.Position -= length;
buffer = new byte[bufferSize]; if (length == end && length > 1) // Valid packet, trigger event
{
var p = Get<PacketManager>().DeserializePacket(ms);
ms.Read(buffer, 0, offset); OnDataReceived(new Articulate_Network.Events.DataReceivedEventArgs()
break; {
}*/ Packet = p
});
}
else
{
Console.WriteLine($"Not a valid packet. Length: {length} - End: {end} - Offset: {offset} - Position: {ms.Position}");
}
} }
} }
}); });

View File

@ -104,15 +104,18 @@ namespace Articulate_Network.Managers
//Console.WriteLine(field.Name); //Console.WriteLine(field.Name);
} }
long length = buffer.Length;
byte[] packetData = buffer.ToArray(); byte[] packetData = buffer.ToArray();
long length = packetData.Length;
buffer.SetLength(0); buffer.SetLength(0);
binaryWriter.Write(6655);
binaryWriter.Write(length); binaryWriter.Write(length);
binaryWriter.Write(packetData); binaryWriter.Write(packetData);
binaryWriter.Write(length); binaryWriter.Write(length);
//Console.WriteLine("Sent bytes: " + length);
watch.Stop(); watch.Stop();
//Console.WriteLine($"Serialize time: {watch.ElapsedTicks / 10} microseconds"); //Console.WriteLine($"Serialize time: {watch.ElapsedTicks / 10} microseconds");
@ -127,7 +130,7 @@ namespace Articulate_Network.Managers
string typeName = reader.ReadString(); string typeName = reader.ReadString();
Console.WriteLine(typeName); //Console.WriteLine(typeName);
Packet packet = packetInstances[typeName];/*(IPacket)Activator.CreateInstance(typeof(T));*/ Packet packet = packetInstances[typeName];/*(IPacket)Activator.CreateInstance(typeof(T));*/
@ -160,6 +163,8 @@ namespace Articulate_Network.Managers
} }
} }
reader.ReadInt64();
watch.Stop(); watch.Stop();
//Console.WriteLine($"Deserialize time: {watch.ElapsedTicks / 10} microseconds"); //Console.WriteLine($"Deserialize time: {watch.ElapsedTicks / 10} microseconds");

View File

@ -61,7 +61,7 @@ namespace Articulate_Network
if (clients[i] == null) if (clients[i] == null)
{ {
clients[i] = client; clients[i] = client;
Console.WriteLine($"Client {i+1} connected from {(client.Client.RemoteEndPoint as IPEndPoint).Address}."); Console.WriteLine($"Client {i + 1} connected from {(client.Client.RemoteEndPoint as IPEndPoint).Address}.");
break; break;
} }
@ -71,7 +71,7 @@ namespace Articulate_Network
} }
} }
public async Task<bool> ReceiveData(TcpClient client) /*public async Task<bool> ReceiveData(TcpClient client)
{ {
await Task.Run(() => await Task.Run(() =>
{ {
@ -102,13 +102,83 @@ namespace Articulate_Network
} }
catch (SocketException e) catch (SocketException e)
{ {
for (int i = 0; i < clients.Length; i++)
if (clients[i] == client) }
}
});
return false;
}*/
public async Task<bool> ReceiveData(TcpClient client)
{ {
clients[i] = null; await Task.Run(() =>
Console.WriteLine($"Client {i+1} lost connection."); {
byte[] buffer = new byte[16384];
int offset = 0;
while (client.Connected)
{
try
{
int bytesToRead = client.Client.Receive(buffer, offset, buffer.Length - offset, SocketFlags.None);
if (bytesToRead == 0)
{
Console.WriteLine("No data.");
continue;
}
var ms = new MemoryStream(buffer);
var br = new BinaryReader(ms);
if (offset > 0)
offset = 0;
while (ms.Position < ms.Length)
{
br.ReadInt32();
int length = (int)br.ReadInt64();
if (length < 0)
break;
if (ms.Position + length > ms.Length)
{
ms.Position -= 8;
buffer = new byte[16384];
offset = (int)(ms.Length - ms.Position);
ms.Read(buffer, 0, offset);
break; break;
} }
ms.Position += length;
int end = (int)br.ReadInt64();
ms.Position -= 8;
if (length == end && length < 1)
break;
ms.Position -= length;
var p = Get<PacketManager>().DeserializePacket(ms);
OnDataReceived(new Articulate_Network.Events.DataReceivedEventArgs()
{
Packet = p,
Client = client
});
br.ReadInt64();
}
}
catch (SocketException e)
{
Console.WriteLine("Client disconnected.");
} }
} }
}); });
@ -122,7 +192,10 @@ namespace Articulate_Network
{ {
byte[] buffer = Get<PacketManager>().SerializePacket(packet); byte[] buffer = Get<PacketManager>().SerializePacket(packet);
tcpClient.Client.Send(buffer, buffer.Length, SocketFlags.None); int sentBytes = tcpClient.Client.Send(buffer, buffer.Length, SocketFlags.None);
if (sentBytes == 0)
Console.WriteLine($"Sent: {sentBytes}");
}); });
return false; return false;