2009-12-30 7 views
1

J'utilise actuellement des sockets pour essayer d'envoyer des messages entre un client Silverlight 3 et un service .NET3.5. Je peux très bien configurer la connexion TCP et envoyer des données, mais mon problème est lié à la sérialisation et à la désérialisation de DataContracts..NET/Silverlight: DataContractSerializer Byte Tableau et sockets: désérialisation EOF inattendue

Actuellement, nous utilisons la liaison WCF PollingDuplex pour faire ce travail, mais nous ne sommes pas satisfaits de ses performances, nous essayons donc des sockets, tout en essayant toujours d'utiliser les attributs de DataContract. Le code que j'ai est la suivante:

// 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; 
} 

Il est la ligne ReadObject qui jette le XmlException: Fin de fichier inattendue. J'ai essayé différentes choses y compris la troncation de 0 à la fin du tableau d'octets (_recieveBuffer) quand il est reçu, en laissant juste un 0 à la fin etc, mais rien ne semble fonctionner. J'ai vérifié les tampons byte [] sur le client et le côté serveur et ils ont les mêmes valeurs au début et à la fin et ont la même longueur. J'ai également essayé d'utiliser actionMessage.GetType() et typeof (ActionMessage) en tant que paramètres de DataContractSerializer, mais il n'y a aucune différence ...

Qu'est-ce que je manque ici: pourquoi dataContractSerializer.Write() n'accepte pas la sortie généré par dataContractSerializer.Read()?

Je passais une bonne journée jusqu'à ce que j'atteigne ce ... J'ai trouvé un autre gars avec le même problème, mais la solution offerte, pour définir memoryStream.Position = 0 du côté service ne fonctionnait pas ...

Merci d'avance.

Répondre

0

Si je devais deviner, je dirais que votre memoryStream.Position = 0; la ligne est au mauvais endroit.

Vous devrez réinitialiser la position dans le flux après avoir écrit le tampon dans le flux.