Я здесь немного рассол.Некоторое время я пытаюсь понять, что я делаю неправильно с асинхронным протоколом TCP.
У меня есть две машины по сети, отправляющие данные из A -> B. Я вычисляю и печатаю MD5 моего byte[]
вобе машины перед отправкой и сразу после получения.
Время от времени, скажем, около 3 секунд, машина, которая получает сообщение, получает поврежденный пакет (другой MD5).Если я запускаю обе программы на локальном хосте, этого не происходит.
Насколько я знаю, этого не должно происходить в TCP, поскольку он обеспечивает доставку и целостность пакета (верно?).Отправляющий код - это просто цикл while, в котором сейчас находится спящий режим.
Вот принимающая сторона:
//We are receiving the package but don't know the size yet
//This -if- is here just to be safe...
if (state.RecvBytesCount < 4)
{
handler.BeginReceive(state.Buffer, state.RecvBytesCount-1, 4 - state.RecvBytesCount, 0, ReadHandler,
state);
}
//Serialized bson contains the size in the first 4 bytes.
if (state.RecvBytesCount == 4)
{
state.TotalPackageSize = BitConverter.ToInt32(state.Buffer, 0);
state.ResetBuffer(state.TotalPackageSize);
var length = BitConverter.GetBytes(state.TotalPackageSize);
state.Buffer[0] = length[0];
state.Buffer[1] = length[1];
state.Buffer[2] = length[2];
state.Buffer[3] = length[3];
//Keep reading...
semaphore.Release();
handler.BeginReceive(state.Buffer, 4, state.TotalPackageSize - 4, 0, ReadHandler,
state);
}
//we already know the package size
else
{
//Not done yet
if (state.RecvBytesCount < state.TotalPackageSize - 4)
{
handler.BeginReceive(state.Buffer, state.RecvBytesCount - 1,
state.TotalPackageSize - state.RecvBytesCount, 0, ReadHandler, state);
semaphore.Release();
}
else
{
PrintMD5(state.Buffer);
byte[] workingBuffer = new byte[state.Buffer.Length];
//TODO: Make the working buffer the size of the received package
Array.Copy(state.Buffer,workingBuffer,state.Buffer.Length);
HandleMessage(workingBuffer, state);
//Prep to receive another package
state.ResetBuffer();
state.RecvBytesCount = 0;
semaphore.Release();
handler.BeginReceive(state.Buffer, 0, 4, 0,
ReadHandler, state);
}
}
В методе HandleMessage
, который я пытался десериализоватьданные, но когда он поврежден, он выдает и исключение.У меня там есть точка останова, которая позволяет мне остановить код и проверить MD5.