2011-07-28 3 views
3

Je rencontre des problèmes lors de l'envoi de données sérialisées via une connexion socket TCP/IP.Sockets C# envoyant des données sérialisées

Ma fonction d'envoi ressemble à ceci:

public void SendData(NetworkConnection connection, ReplicableObject ro) { 
      MemoryStream ms = new MemoryStream(); 
      BinaryFormatter bf = new BinaryFormatter(); 
      bf.Serialize(ms, ro); 

      ms.WriteTo(connection.TcpStream); 
      connection.TcpStream.Flush(); 

      ms.Close(); 
     } 

Je suis conscient que actuellement TcpStream.Flush() ne fait rien. Ce n'est pas mon problème, de toute façon.

Sur la réception (client) fin, le lecteur ressemble à ceci:

byte[] readBuffer = new byte[8192]; 
      worldMapStream = worldMapConnection.GetStream(); 
      BinaryFormatter bf = new BinaryFormatter(); 
      MemoryStream ms = new MemoryStream(); 
      IsConnectedToWorldMap = true; 
      while (true) { 
       try { 
        do { 
         int bytes = worldMapStream.Read(readBuffer, 0, readBuffer.Length); 
         ms.Write(readBuffer, 0, bytes); 
        } 
        while (worldMapStream.DataAvailable); 

        try { 
         ReplicableObject ro = (ReplicableObject) bf.Deserialize(ms); 
         ro = ro; 
        } 
        catch (Exception e) { 
         e = e; 
        } 
       } 

L'étrange ro = ro et e = lignes e sont juste là pour que je puisse en ajouter un.

Mon problème est le suivant: La lecture échoue toujours. Une exception est interceptée et le message explique que la fin du flux a été atteinte avant la fin de l'analyse syntaxique. Maintenant, je comprends que les données peuvent ne pas toutes arriver dans un morceau, mais je n'ai pas effacé le flux de mémoire en attrapant une exception, donc le morceau suivant devrait simplement ajouter les données restantes sur la fin de celui-ci, non? Mais cela ne fonctionne pas, apparemment.

Alors, qu'est-ce que je fais de mal? Merci d'avance. :)

P.S. Je comprends que WCF est la meilleure alternative à cela; mais malheureusement je ne peux pas l'utiliser dans ce projet.

Répondre

2

Here we go:

while (worldMapStream.DataAvailable); 

devrait être:

while(bytes>0); 

Ce qui signifie également le déplacement bytes en dehors de la boucle.

DataAvailable signifie juste "maintenant, à la carte réseau". Cela ne vous dit pas si d'autres viendront ou non. En outre, vous devez seulement écrire quand bytes>0 aussi; pour être honnête une boucle while est plus facile ici :)

Ensuite; après avoir rempli ms, définissez ms.Position = 0 pour rembobiner le flux.

+0

Je suis désolé, je dois mal comprendre ... Sûrement cette boucle ne sera jamais abandonnée alors? Comme chaque fois que tcpstream est lu à partir d'octets, il sera supérieur à 0; l'amenant à revenir au début de la boucle et à relire? – Xenoprimate

+0

@Motig il reviendra <= 0 lorsqu'il est fermé. En outre, il ya un deuxième bug - voir modifier –

+0

@Motig - aussi, je * ne * * pense que WCF serait mieux ici; mais je peux suggérer un meilleur serializer que BinaryFormatter si vous aimez :) –

Questions connexes