.NET / Silverlight: байтовый массив и сокеты DataContractSerializer: неожиданная десериализация EOF

В настоящее время я использую сокеты для отправки сообщений между клиентом Silverlight 3 и службой .NET3.5. Я могу нормально настроить TCP-соединение и отправлять данные, но моя проблема связана с сериализацией и десериализацией DataContracts.

В настоящее время мы используем привязку WCF PollingDuplex для выполнения этой работы, но мы недовольны ее производительностью, поэтому пытаемся использовать сокеты, но все еще пытаемся использовать атрибуты DataContract. У меня есть следующий код:

// Client
public void Send(ActionMessage actionMessage)
{
        DataContractSerializer dcs =
            new DataContractSerializer(actionMessage.GetType());

        MemoryStream memoryStream = new MemoryStream();

        dcs.WriteObject(memoryStream, actionMessage);

        byte[] sendBuffer = new byte[4096];
        memoryStream.Position = 0;
        memoryStream.Read(sendBuffer, 0, sendBuffer.Length);

        SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs();

        socketAsyncEventArgs.SetBuffer(sendBuffer, 0, sendBuffer.Length);

        if(!_socket.SendAsync(socketAsyncEventArgs))
            HandleSendComplete(socketAsyncEventArgs);
    }

// Service

private byte[] _recieveBuffer = new byte[4096];
private int _receivedLength;

private void socket_OnReceiveComplete(IAsyncResult asyncResult)
{
        _receivedLength += _tcpClient.Client.EndReceive(asyncResult);

        // See if there's more data that we need to grab
        if (_receivedLength < _recieveBuffer.Length)
        {
            // Need to grab more data so receive remaining data
            _tcpClient.Client.BeginReceive(_recieveBuffer, _receivedLength,
                _recieveBuffer.Length - _receivedLength, SocketFlags.None,
                new AsyncCallback(socket_OnReceiveComplete), null);

            return;
        }

        MemoryStream memoryStream = new MemoryStream();

        memoryStream.Position = 0;
        memoryStream.Write(_recieveBuffer, 0, _recieveBuffer.Length);

        DataContractSerializer dcs = new DataContractSerializer(typeof(ActionMessage));

        object o = dcs.ReadObject(memoryStream);

        ActionMessage actionMessage = (ActionMessage) o;
}

Это строка ReadObject, которая вызывает исключение XmlException: Unexpected End of File. Я пробовал разные вещи, включая усечение завершающих 0 из байтового массива (_recieveBuffer) при его получении, оставляя только один 0 в конце и т.д., но, похоже, ничего не работает. Я проверил буферы byte [] на стороне клиента и на стороне сервера, и они имеют одинаковые значения в начале и в конце и имеют одинаковую длину. Я также пробовал использовать actionMessage.GetType () и typeof (ActionMessage) в качестве параметров DataContractSerializer, но нет никакой разницы ...

Что я здесь упускаю: почему dataContractSerializer.Write () не принимает вывод, сгенерированный dataContractSerializer.Read ()?

У меня был хороший день, пока я не нажал на это ... Я нашел еще одного парня с той же проблемой, но предложенное решение, чтобы установить memoryStream.Position = 0 на стороне службы, не сработало ...

Заранее спасибо.


person MrLane    schedule 30.12.2009    source источник


Ответы (1)


Если бы мне пришлось угадывать, я бы сказал, что your memoryStream.Position = 0; линия находится не в том месте.

Вам нужно будет сбросить позицию в потоке после записи буфера в поток.

person Scott P    schedule 18.02.2010