Frage

Einfach habe ich versucht, das umzusetzen, was BufferedStreamReader in Java tut. Ich habe einen Socket-Stream offen und will es einfach in einer Linie orientiert lesen - Zeile für Zeile

.

Ich habe den folgenden Server-Code.

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

Und der folgende Client-Code:

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

Der Server liest nur die erste Zeile (login>user,pass) und kehrt dann ReadLine null!

Was ist der einfachste Weg, diese Linie orientierte Leser zu erreichen, wie es in Java BufferedStreamReader ist? : S

War es hilfreich?

Lösung

Ein typischer Line-Leser ist so etwas wie:

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

(beachten Sie die using, um sicherzustellen, wir Dispose() es auch dann, wenn wir einen Fehler, und die Schleife)

Wenn Sie möchten, Sie könnten abstrakt diese (Trennung von Bedenken) mit einem Iteratorblock:

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

(beachten wir diese in eine Funktion verschoben haben und entfernt die „etwas tun“, es mit „yield return“ zu ersetzen, die einen Iterator erzeugt (eine träge iteriert, nicht-Pufferzustandsmaschine)

Wir würden dann verbrauchen diese so einfach wie:

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

Jetzt ist unser Verarbeitungscode braucht nicht zu befürchten wie Zeilen zu lesen -. Einfach gegeben eine Folge von Linien, etwas mit ihnen

Beachten Sie, dass die using (Dispose()) auch TcpClient gilt; Sie sollten eine Gewohnheit der Überprüfung für IDisposable machen; zum Beispiel (auch noch Ihre Fehlerprotokollierung):

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

Andere Tipps

Die während in der Server-Code ist Setup nur pro Verbindung eine Zeile zu lesen. Sie werden noch eine Weile im try müssen alle Leitungen geschickt zu lesen. Ich denke einmal, dass Strom-Setup auf der Client-Seite ist, es alle Daten senden wird. Dann auf der Serverseite Stream ist effektiv nur eine Zeile von diesem bestimmten Strom zu lesen.

versucht, diese und bekam

Der Typ oder Namespace-Name 'Stream konnte nicht gefunden werden (möglicherweise fehlt eine using-Direktive oder ein Assemblyverweis?) Der Typ oder Namespace-Name ‚Stream‘ konnte nicht gefunden werden (möglicherweise fehlt eine using-Direktive oder ein Assemblyverweis?) Der Typ oder Namespace-Name ‚Stream‘ konnte nicht gefunden werden (möglicherweise fehlt eine using-Direktive oder ein Assemblyverweis?) 'System.Net.Sockets.Socket' enthält keine Definition für '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 ist eine Buchse. für einige rezone nicht richtig auf meinem PC arbeitet mehr die TcpClient Klasse überhaupt, aber die Socket-Klasse funktioniert gut.

UTF-8 ist der gestrandeten Stream / Writer Encoding

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top