C# - StreamReader.ReadLine does not work properly!

前端 未结 4 1138
南方客
南方客 2020-12-09 19:37

Simply I have been trying to implement what BufferedStreamReader does in Java. I have a socket stream open and just want to read it in a line-oriented fashion -

相关标签:
4条回答
  • 2020-12-09 20:12

    Tried this and got

    The type or namespace name 'Stream' could not be found (are you missing a using directive or an assembly reference?) The type or namespace name 'StreamReader' could not be found (are you missing a using directive or an assembly reference?) The type or namespace name 'StreamReader' could not be found (are you missing a using directive or an assembly reference?) 'System.Net.Sockets.Socket' does not contain a definition for 'GetStream'

    0 讨论(0)
  • 2020-12-09 20:21
        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 讨论(0)
  • 2020-12-09 20:26

    A typical line-reader is something like:

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

    (note the using to ensure we Dispose() it even if we get an error, and the loop)

    If you want, you could abstract this (separation of concerns) with an iterator block:

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

    (note we've moved this into a function and removed the "do something", replacing it with "yield return", which creates an iterator (a lazily iterated, non-buffering state machine)

    We would then consume this as simply as:

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

    Now our processing code doesn't need to worry about how to read lines - simply given a sequence of lines, do something with them.

    Note that the using (Dispose()) applies to TcpClient too; you should make a habit of checking for IDisposable; for example (still including your error-logging):

    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());
        }
    }
    
    0 讨论(0)
  • 2020-12-09 20:29

    The while in your server code is setup to only read one line per connection. You'll need another while within the try to read all of the lines being sent. I think once that stream is setup on the client side, it is going to send all of the data. Then on the server side, your stream is effectively only reading one line from that particular stream.

    0 讨论(0)
提交回复
热议问题