J
jkv
Hi,
I am developing a application which have to continue working even in a
high packet loss environment, i have attached the serialization and
network transmission parts from both the server and client.
It works when there are no packet loss, but when introducing severe
packet loss (10%) it starts crashing because the ' int size =
br.ReadInt32();' in the server snippets reads some random data.
My thoughts on how to fix this is to introduce a uniq prefix and
postfix on ms.ToArray().Length(fx. ???!!!512!!!???) and send this
string instead of just 'bw.Write(ms.ToArray().Length);'.
But how would i make the server catch this "delimited" string? The
idea is to let the server skip data until it reaches the delimited
string and then afterwards start deserialization as normal, and handle
any deserialization faults with try/catch.
I'm fully aware the the above solution would very likely miss alot of
objects - but that dosent really matter.
Any hints on a the above - or anyone got a idea for an entirely
differnt approach?
Regards,
Johnny
---CLIENT SNIPPET--
private void Sendchannel()
{
BinaryWriter bw = new BinaryWriter(_clientStream);
Int32 sizeOfPacket;
while (!SharedObjects.ShuttingDown)
{
while (SharedObjects.clientOutgoingQueue.Count !=
0)
{
Common.SIO obj =
SharedObjects.clientOutgoingQueue.Dequeue();
MemoryStream ms = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
bw.Write(ms.ToArray().Length);
_clientStream.Flush();
bw.Write(ms.ToArray());
_clientStream.Flush();
}
Thread.Sleep(100);
}
}
---SERVER SNIPPET---
private void receiveChannel(NetworkStream clientstream)
{
Int32 sizeOfPacket;
BinaryReader br = new BinaryReader(clientstream);
BinaryWriter bw = new BinaryWriter(clientstream);
while (!SharedObjects.ShuttingDown)
{
if (clientstream.DataAvailable)
{
byte[] message = new byte[4096];
int size = br.ReadInt32();
MemoryStream ms = new MemoryStream();
message = br.ReadBytes(size);
ms.Write(message, 0, message.Length);
IFormatter formatter = new BinaryFormatter();
ms.Seek(0, SeekOrigin.Begin);
Common.SIO testsio =
(Common.SIO)formatter.Deserialize(ms);
SharedObjects.IncommingQueue.Enqueue(testsio);
}
else
{
Thread.Sleep(100);
}
}
}
I am developing a application which have to continue working even in a
high packet loss environment, i have attached the serialization and
network transmission parts from both the server and client.
It works when there are no packet loss, but when introducing severe
packet loss (10%) it starts crashing because the ' int size =
br.ReadInt32();' in the server snippets reads some random data.
My thoughts on how to fix this is to introduce a uniq prefix and
postfix on ms.ToArray().Length(fx. ???!!!512!!!???) and send this
string instead of just 'bw.Write(ms.ToArray().Length);'.
But how would i make the server catch this "delimited" string? The
idea is to let the server skip data until it reaches the delimited
string and then afterwards start deserialization as normal, and handle
any deserialization faults with try/catch.
I'm fully aware the the above solution would very likely miss alot of
objects - but that dosent really matter.
Any hints on a the above - or anyone got a idea for an entirely
differnt approach?
Regards,
Johnny
---CLIENT SNIPPET--
private void Sendchannel()
{
BinaryWriter bw = new BinaryWriter(_clientStream);
Int32 sizeOfPacket;
while (!SharedObjects.ShuttingDown)
{
while (SharedObjects.clientOutgoingQueue.Count !=
0)
{
Common.SIO obj =
SharedObjects.clientOutgoingQueue.Dequeue();
MemoryStream ms = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
bw.Write(ms.ToArray().Length);
_clientStream.Flush();
bw.Write(ms.ToArray());
_clientStream.Flush();
}
Thread.Sleep(100);
}
}
---SERVER SNIPPET---
private void receiveChannel(NetworkStream clientstream)
{
Int32 sizeOfPacket;
BinaryReader br = new BinaryReader(clientstream);
BinaryWriter bw = new BinaryWriter(clientstream);
while (!SharedObjects.ShuttingDown)
{
if (clientstream.DataAvailable)
{
byte[] message = new byte[4096];
int size = br.ReadInt32();
MemoryStream ms = new MemoryStream();
message = br.ReadBytes(size);
ms.Write(message, 0, message.Length);
IFormatter formatter = new BinaryFormatter();
ms.Seek(0, SeekOrigin.Begin);
Common.SIO testsio =
(Common.SIO)formatter.Deserialize(ms);
SharedObjects.IncommingQueue.Enqueue(testsio);
}
else
{
Thread.Sleep(100);
}
}
}