Question

Simplement j'ai essayé de mettre en œuvre ce que BufferedStreamReader fait en Java. J'ai un flux de socket ouvert et que vous voulez juste de le lire d'une manière orientée ligne - ligne par ligne

.

J'ai le code serveur suivant.

while (continueProcess)
        {
            try
            {
                StreamReader reader = new StreamReader(Socket.GetStream(), Encoding.UTF8);
                string command = reader.ReadLine();
                if (command == null)
                    break;

                OnClientExecute(command);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

Et le client code suivant:

TcpClient tcpClient = new TcpClient();
        try
        {
            tcpClient.Connect("localhost", serverPort);
            StreamWriter writer = new StreamWriter(tcpClient.GetStream(), Encoding.UTF8);
            writer.AutoFlush = true;
            writer.WriteLine("login>user,pass");
            writer.WriteLine("print>param1,param2,param3");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
        finally
        {
            tcpClient.Close();
        }

Le serveur ne lit que la première ligne (de login>user,pass) puis ReadLine retourne null!

Quelle est la meilleure façon d'atteindre ce lecteur orienté ligne comme dans la BufferedStreamReader Java? : S

Était-ce utile?

La solution

Une ligne typique est-lecteur quelque chose comme:

using(StreamReader reader = new StreamReader(Socket.GetStream(), Encoding.UTF8)) {
    string line;
    while((line = reader.ReadLine()) != null) {
        // do something with line
    }
}

(notez le using pour nous assurer Dispose() même si nous obtenons une erreur, et la boucle)

Si vous voulez, vous pourriez abstraite cette (séparation des préoccupations) avec un bloc itérateur:

static IEnumerable<string> ReadLines(Stream source, Encoding encoding) {
    using(StreamReader reader = new StreamReader(source, encoding)) {
        string line;
        while((line = reader.ReadLine()) != null) {
            yield return line;
        }
    }
}

(noter que nous avons déplacé cela en fonction et a retiré le « faire quelque chose », en le remplaçant par « retour de rendement », ce qui crée un iterator (une, machine d'état non-tampon paresseusement itéré)

Nous pourrions alors consommer ce aussi simple que:

foreach(string line in ReadLines(Socket.GetStream(), Encoding.UTF8)) {
    // do something with line
}

Maintenant, notre code de traitement n'a pas besoin de vous soucier de comment pour lire les lignes -. Simplement donnée une séquence de lignes, faire quelque chose avec eux

Notez que le using (Dispose()) applique à TcpClient aussi; vous devez prendre l'habitude de vérifier les IDisposable; par exemple (y compris encore votre diagraphie d'erreur):

using(TcpClient tcpClient = new TcpClient()) {
    try {
       tcpClient.Connect("localhost", serverPort);
       StreamWriter writer = new StreamWriter(tcpClient.GetStream(), Encoding.UTF8);
       writer.AutoFlush = true;
       writer.WriteLine("login>user,pass");
       writer.WriteLine("print>param1,param2,param3");
    } catch (Exception ex) {
        Console.Error.WriteLine(ex.ToString());
    }
}

Autres conseils

Le tout dans votre code de serveur est configuré pour lire une seule ligne par connexion. Vous aurez besoin d'un autre tout dans le essayer de lire toutes les lignes envoyées. Je pense qu'une fois ce flux est configuré sur le côté client, il va envoyer toutes les données. Ensuite, sur le côté serveur, votre flux est effectivement lu une seule ligne de ce courant particulier.

essayé et a obtenu

Le type ou le nom namespace Stream 'n'a pas pu être trouvée (vous manque une directive à l'aide ou une référence d'assemblage?) Le type ou le nom namespace « StreamReader » n'a pas pu être trouvée (vous manque une directive à l'aide ou une référence d'assemblage?) Le type ou le nom namespace « StreamReader » n'a pas pu être trouvée (vous manque une directive à l'aide ou une référence d'assemblage?) « System.Net.Sockets.Socket » ne contient pas de définition pour « GetStream »

    public string READS()
    {
        byte[] buf = new byte[CLI.Available];//set buffer
        CLI.Receive(buf);//read bytes from stream
        string line = UTF8Encoding.UTF8.GetString(buf);//get string from bytes
        return line;//return string from bytes
    }
    public void WRITES(string text)
    {
        byte[] buf = UTF8Encoding.UTF8.GetBytes(text);//get bytes of text
        CLI.Send(buf);//send bytes
    }

CLI est une douille. pour certains rezonage la classe TcpClient ne fonctionne pas correctement sur mon pc plus, mais la classe Socket fonctionne très bien.

UTF-8 est le codage StreamReader / enregistreur brin

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top