Pregunta

Simplemente he estado tratando de poner en práctica lo hace BufferedStreamReader en Java. Tengo un flujo de socket abierto y sólo quiero leerlo de una manera orientada a la línea - línea por línea

.

Tengo el siguiente servidor de código.

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

Y el cliente siguiente código:

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

El servidor sólo lee la primera línea (login>user,pass) y luego ReadLine devuelve un valor nulo!

¿Cuál es la forma más fácil de lograr este lector orientado a líneas como lo es en BufferedStreamReader de Java? : S

¿Fue útil?

Solución

Una línea-lector típico es algo como:

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

(nótese el using para asegurar que Dispose() que incluso si conseguimos un error, y el bucle)

Si lo desea, podría Resumen Este (separación de intereses) con un bloque de iterador:

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

(en cuenta que hemos pasado esto en una función y eliminado el "hacer algo", sustituyéndolo por "retorno de rendimiento", lo que crea un iterador (un perezosamente iterado, la máquina de estado no-buffering)

Nos entonces consumir esta tan simple como:

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

Ahora nuestro código de procesamiento no necesita preocuparse por ¿Cómo para leer líneas -. Simplemente dada una secuencia de líneas, hacer algo con ellos

Tenga en cuenta que la using (Dispose()) se aplica a TcpClient también; usted debe hacer un hábito de comprobación de IDisposable; por ejemplo (aún incluyendo su registro de errores):

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

Otros consejos

El tiempo en el código del servidor se configure sólo para leer una línea por cada conexión. Usted necesitará otra, mientras que en el intento de leer todas las líneas que se envía. Creo que una vez que la corriente está configurado en el lado del cliente, que va a enviar todos los datos. A continuación, en el lado del servidor, su flujo es de hecho solo leer una línea de esa corriente en particular.

intentado esto y tiene

El tipo o espacio de nombres 'corriente' no se pudo encontrar (¿falta una directiva using o una referencia de ensamblado?) El tipo o espacio de nombres 'StreamReader' no se pudo encontrar (¿falta una directiva using o una referencia de ensamblado?) El tipo o espacio de nombres 'StreamReader' no se pudo encontrar (¿falta una directiva using o una referencia de ensamblado?) 'System.Net.Sockets.Socket' no contiene una definición para '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 es un socket. por alguna Rezone la clase TcpClient no funciona bien en mi pc más, pero la clase Socket funciona muy bien.

UTF-8 es la StreamReader / Codificación escritor hebra

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top