11
votes

C # - StreamReader.Readline ne fonctionne pas correctement!

J'essaie simplement de mettre en œuvre ce que bufferedreamreader code> fait en Java. J'ai un flux de socket ouvert et je veux juste le lire dans une ligne de mode orientée ligne par ligne.

J'ai le code serveur suivant. P>

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();
        }


2 commentaires

S'il vous plaît, éliminez vos objets ici (le streamweader et le streamwriter). Sinon, vous pouvez avoir des problèmes inattendus. Il suffit de mettre un bloc d'utilisation autour d'eux (comme en utilisant (Streamwriter Writer = ...) {}), et vous allez bien


Non pas que c'était pertinent pour la question - juste une suggestion.


4 Réponses :


5
votes

Le temps dans votre code serveur est configuré pour lire une seule ligne par connexion. Vous aurez besoin d'un autre pendant que vous essayez de lire toutes les lignes envoyées. Je pense qu'une fois que ce flux est configuré du côté du client, il va envoyer toutes les données. Ensuite, sur le côté serveur, votre flux ne lisait efficacement qu'une ligne de ce flux particulier.


2 commentaires

Après avoir modifié mon serveur et mon code client comme suit Server Server: Utilisation (StreamReader Reader = Nouveau StreamReader (Socket.Getstream (), Encoding.UtF8)) {Tandis (Continurocess) .... Client.sleep (10000) ; écrivain.writeline ("Imprimer> Test, un, deux"); J'ai inséré thread.sleep (10000) à mon code client et que le serveur a commencé à lancer une exception. La prise du client sera ouverte jusqu'à ce que les sorties du client et, étant donné que le client enverra des données tout au long de son cycle de vie semble que ce code lancera une erreur. Tu ne le penses pas?


Sans voir quel est le nouveau code ou nouvelle exception, je ne suis pas sûr de ce que le problème pourrait être.



16
votes

Un lecteur de ligne typique est quelque chose comme: xxx pré>

(notez le en utilisant code> pour vous assurer que nous disposons code> même si Nous obtenons une erreur, et la boucle) p>

Si vous le souhaitez, vous pouvez abstraire ceci (séparation des préoccupations) avec un bloc Itérateur: p> xxx pré>

( note que nous avons déplacé cela dans une fonction et supprimé le "faire quelque chose", le remplaçant par "retour de rendement", qui crée un itérateur (une machine à états itérale paresseux non mise à tamponner) p>

Nous serions alors Consommez ceci comme tout simplement comme suit: p> xxx pré>

Notre code de traitement n'a pas besoin de vous inquiéter de comment em> lire des lignes - simplement donné une séquence de lignes, faites quelque chose avec eux. p>

Notez que le à l'aide de code> ( Dispose () code>) s'applique à tcpclient aussi; vous devez avoir l'habitude de vérifier iDisposable code>; par exemple (incluant toujours votre journalisation d'erreur): p>

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());
    }
}


2 commentaires

Lorsque j'utilise StreamReader pour la lecture de la prise, j'ai constaté que le programme client congélait, prenant une durée infinie de temps à la méthode readline () et enfin de ne pas lire.


@ MASUDRAHMAN qui signifie généralement soit: le serveur n'envoie pas de ligne complète (c'est-à-dire que vous lui demandez d'attendre quelque chose que le serveur n'a pas de raison de vous envoyer), ou le serveur a oublié de rincer une sortie. amortir. Vous peut ajouter un délai de lecture, mais finalement, il ne peut pas faire envoyer les données du serveur. Vous pouvez bien sûr faire la lecture et vous tamponner, mais cela change simplement la nature du problème - il peut alors être votre travail pour décider qu'une ligne complète n'a pas été envoyée après une certaine période de temps.



-2
votes

essayé cela et obtenu

Le nom de type ou d'espace de noms 'flux' n'a pas pu être trouvé (manquez-vous une directive ou une référence d'assemblage?) Le nom de type ou d'espace de noms «StreamReader» n'a pas pu être trouvé (manquez-vous une directive ou une référence d'assemblage?) Le nom de type ou d'espace de noms «StreamReader» n'a pas pu être trouvé (manquez-vous une directive ou une référence d'assemblage?) 'System.net.sockets.socket' ne contient pas de définition pour 'getStream'


0 commentaires

0
votes
    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 is a socket.
for some rezone the TcpClient class doesn't work right on my pc any more,
but the Socket class works just fine.UTF-8 is the stranded StreamReader / Writer Encoding

0 commentaires