Поврежденный пакет по асинхронному TCP в C # - PullRequest
0 голосов
/ 23 мая 2018

Я здесь немного рассол.Некоторое время я пытаюсь понять, что я делаю неправильно с асинхронным протоколом 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.

...