2017-04-05 4 views
1

Habituellement, je suis capable de résoudre les problèmes par moi-même, mais encore une fois, je dois demander de l'aide. Je m'excuse d'avance si quelque chose est incohérent, car il semble que j'ai un peu de fièvre. Je suis en train de faire un jeu vraiment simple dans XNA. C'est un jeu de tir 2D. La seule action est le joueur tirant des balles. La chose est, je veux le rendre multijoueur (joueurs dans le même réseau).Socket WriteLine/ReadLine ne correspond pas

Je l'ai considéré comme approche suivante:

  1. L'un des joueurs serveur héberge

    • serveur contient des informations sur la position de chaque joueur et balle
    • serveur crée un nouveau monde (composé de joueurs et puces) et le met à jour dans un nouveau fil comme celui-ci:

      while (true) 
          { 
           lock (world) world.update(); 
           Thread.Sleep(worldUpdatePeriod); 
          } 
      
    • Server crée une nouvelle discussion pour chaque joueur qui doit être manipulé

  2. Les joueurs se connectent au serveur

    • Ils doivent recevoir périodiquement des informations du serveur que doivent-ils tirer:

      class Asset 
      { 
          string type; 
          Vector2 position; 
      } 
      
    • Ils devraient être en mesure d'envoyer une entrée à partir du clavier et la souris pour bouger et tirer.

maintenant au point. Le joueur est en mesure d'envoyer trois types de messages sur le serveur:

  • "PEUT LIRE"
  • "souris"
  • "CLAVIER"

    string header = "CAN READ"; 
    lock (streamWriter) { streamWriter.WriteLine(header); } 
    

Server, dans un thread distinct pour chaque client attend des messages

streamReader = new StreamReader(networkStream); 
streamWriter = new StreamWriter(networkStream); 
streamWriter.AutoFlush = true; 

while (true) 
{ 
    if (networkStream.DataAvailable) 
    { 
     string header; 
     lock (streamReader) 
     { 
      header = Convert.ToString(streamReader.ReadLine()); 
      Console.WriteLine($"Header received: {header}"); 
      handleHeader(header); 
     } 
    } 
} 

Maintenant, si l'en-tête est, par exemple, "peut-il lire"

  1. serveur

    case "CAN READ": 
        if (streamWriter.BaseStream.CanRead) 
        { 
         lock (streamWriter) 
         { 
          streamWriter.WriteLine(server.world.assets.Count); 
    
          foreach (var asset in server.world.assets) 
          { 
           streamWriter.WriteLine(asset.type); 
           streamWriter.WriteLine(asset.position.X); 
           streamWriter.WriteLine(asset.position.Y); 
          } 
         } 
        } 
        break; 
    
  2. client

    int assetCount = Convert.ToInt32(streamReader.ReadLine()); 
    List<Asset> receivedAssets = new List<Asset>(); 
    
    lock (streamReader) 
    { 
    
        for (int i = 0; i < assetCount; i++) 
        { 
         string type = Convert.ToString(streamReader.ReadLine()); 
         int x = Convert.ToInt32(streamReader.ReadLine()); 
         int y = Convert.ToInt32(streamReader.ReadLine()); 
    
         receivedAssets.Add(new Asset(type, new Vector2(x, y))); 
        } 
        return receivedAssets; 
    } 
    

Bien sûr classe Client et la classe handleClient ont streamReaders distinct nad streamWriters.

Vous avez l'idée. J'essaye de faire correspondre chaque WriteLine() du serveur avec ReadLine() du client et ainsi de suite. Et ça fonctionne bien! Jusqu'à ce que j'ajoute l'entrée de l'utilisateur au mélange. Une fois que j'envoie une entrée au clavier (comme indiqué ci-dessus), cela semble fonctionner, avec occasionnellement System.FormatException, ce qui signifie que ReadLine() a lu WriteLine() incorrect. Je suis capable d'attraper cela et de réessayer.

Et tout va à l'enfer une fois que j'envoie la souris. Les exceptions incompatibles deviennent plus fréquentes au point que le 'jeu' est injouable. Je me demande donc si quelque chose ne va pas dans mon approche. Je m'excuse pour la longueur de la question, j'ai essayé d'être concis mais aussi senti besoin de fournir un contexte. Merci, si vous l'avez fait jusqu'à la fin, je serai heureux de répondre à d'autres questions que j'essaie de résoudre pour les derniers jours.

+0

Connexions TCP? TCP est un protocole de streaming, sans concept de limites de message. Consultez http://stackoverflow.com/questions/17446491/tcp-stream-vs-udp-message pour une seule question similaire. –

Répondre

1

J'ai lu le lien qu'Andrew m'a fourni et j'ai réussi à le faire fonctionner. Comment? Utilisation à la fois du client TCP (pour configurer la connexion, lire l'entrée du client) et du client UDP (pour diffuser des ressources sur chaque client). Juste poster cela au cas où quelqu'un rencontrerait un tel problème dans le futur, ce dont je doute fortement.

À la votre!